Ubuntu下使用Expect自动化需交互进程时后台运行报错问题
我完全懂你遇到的这个困扰——前台跑Expect脚本明明一切正常,一放到后台加&运行就弹出liner: function not supported in this terminal错误,太影响效率了。咱们来拆解下问题,再给你几个可行的解决办法。
问题根源
你脚本里的interact和expect_background这两个命令是关键。interact是用来把控制权交还给用户,让用户和 spawn 的进程直接交互;expect_background则是在后台监听进程输出。但当你把脚本放到后台运行时,进程脱离了当前终端的交互环境,这两个依赖终端交互的命令就找不到合适的终端支持,自然就报错了。
解决方案
方案1:移除不必要的交互命令(最推荐)
如果你的startclef.cmd进程在输入完密码之后就自动完成任务,不需要后续人工交互,那完全可以删掉interact和expect_background,换成等待进程结束的expect eof。修改后的脚本如下:
#!/usr/bin/expect -f spawn -ignore HUP /home/startclef.cmd expect "ok" send "ok\r" sleep 5 expect "Please enter the password to decrypt the master seed" sleep 5 send "pass_123\r" # 等待进程自然结束,替代interact和expect_background expect eof
修改后直接后台运行./script.expect &就不会报错了,脚本会自动等待进程完成后退出。
方案2:用nohup让进程脱离终端运行
如果确实需要保留interact(比如进程后续还有交互需求),可以用nohup命令来启动脚本,同时重定向输出到日志文件,避免终端依赖问题:
nohup ./script.expect > output.log 2>&1 &
nohup会让进程忽略挂起信号,脱离当前终端,输出和错误信息都会写到output.log里,你后续可以通过查看日志了解进程状态。
方案3:用unbuffer提供伪终端
如果上面两种方法都不满足你的需求,还可以用unbuffer工具给脚本提供一个伪终端,让进程以为自己在和真实终端交互。首先需要安装依赖包:
sudo apt-get install expect-dev
然后用unbuffer后台运行脚本:
unbuffer ./script.expect > output.log 2>&1 &
这样interact之类的交互命令就能正常工作了。
你可以根据自己的实际需求选其中一个方案试试,一般方案1就能解决大部分场景的问题啦。
备注:内容来源于stack exchange,提问作者Abdulhamid

