You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Git Hook使用/dev/tty后如何重定向输入实现自动化测试?

解决Git Hook中exec < /dev/tty的测试输入问题

你的核心问题在于exec < /dev/tty强制脚本的标准输入绑定到真实终端(键盘),而管道输入(echo ... |)是通过另一个文件描述符传递的,根本没进入脚本的输入流——你用tee /dev/tty只是把内容打印到屏幕,但脚本的read依然在等待键盘输入,所以message变量不会被设置。

下面提供几种可行的解决方法:

方法1:用script命令模拟伪终端

script可以创建一个伪终端(PTY),让脚本的/dev/tty指向这个伪终端,同时把管道输入转发进去。直接运行:

echo -e "foo\n" | script -q -c "./target.sh" /dev/null
  • -q:静默模式,不显示script的启动/结束信息
  • -c "./target.sh":指定要运行的脚本
  • /dev/null:把script的日志输出丢到空设备,避免额外干扰输出

运行后你会看到脚本正确读取到foo,输出The message foo。

方法2:用expect自动化终端交互

如果需要模拟更复杂的多步交互场景,expect是专门用来处理终端交互的工具。写一个简单的expect脚本(比如命名为test_target.exp):

#!/usr/bin/expect
spawn bash target.sh
expect "Type a message: "  # 等待脚本的输入提示符
send "foo\n"               # 自动发送输入内容
expect eof                 # 等待脚本执行结束

给脚本添加执行权限:

chmod +x test_target.exp

然后直接运行脚本即可完成自动化测试:

./test_target.exp

方法3:给脚本增加测试模式(推荐用于Git Hook场景)

如果你不想依赖额外工具,可以修改脚本,增加一个测试开关,让测试时用标准输入,实际运行时保留/dev/tty的交互逻辑:

# file: target.sh
# 检查是否处于测试模式
if [[ -n "$GIT_HOOK_TEST" ]]; then
    read -p "Type a message: " message
else
    exec < /dev/tty
    read -p "Type a message: " message
fi
echo "The message ${message}"

测试时通过环境变量开启测试模式,用管道输入测试内容:

GIT_HOOK_TEST=1 echo -e "foo\n" | bash target.sh

实际作为Git Hook运行时,因为没有设置GIT_HOOK_TEST变量,脚本会自动用/dev/tty和用户交互,完全不影响原有功能。


内容的提问来源于stack exchange,提问作者Common Sense

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:38:01