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

能否让expect修改子进程tty状态匹配interact模式而不使用interact?

问题描述

现有一段用于自动化无源码程序X审批流程的Expect脚本:

eval spawn $argv

set timeout -1
expect -ex {Approve Request}
sleep 1
send "y\r"
interact

该脚本可正常执行并退出;但将最后一行的interact替换为expect eof后,程序X会挂起。通过expect -d日志发现:使用interact时,程序X接收y后会继续输出并发送EOF;替换为expect eof后,程序X接收y后停止输出,需手动用Control-C终止。推测程序X的行为与tty状态相关,尝试过设置stty_init及spawn -nottycopy:

set stty_init "raw -echo"
eval spawn -nottycopy $argv

但无预期效果,现需实现:不使用interact,让Expect将子进程的tty状态修改为interact模式下的状态。

解决方案

1. 先获取interact模式下的tty属性

运行原脚本(带interact),在程序进入interact阶段后,按Ctrl+Z挂起Expect进程,找到程序X的PID,执行以下命令查看其tty属性:

stty -a -F /proc/<程序X的PID>/fd/0

记录输出中的所有属性(比如icanon echo intr ^c等)。

2. 在脚本中手动设置tty属性

将步骤1中记录的属性通过Expect的stty命令设置给子进程,替换expect eof的脚本示例:

eval spawn $argv

# 设置为interact模式下的tty属性,替换为你实际获取到的内容
stty icanon echo intr ^c quit ^\\ erase ^? kill ^U eof ^D start ^Q stop ^S susp ^Z rprnt ^R flush ^O werase ^W lnext ^V -ixon -ixoff

set timeout -1
expect -ex {Approve Request}
sleep 1
send "y\r"
expect eof

也可以将属性写入stty_init变量,在spawn时生效:

# 替换为你实际获取到的interact模式tty属性
set stty_init "icanon echo intr ^c quit ^\\ erase ^? kill ^U eof ^D start ^Q stop ^S susp ^Z rprnt ^R flush ^O werase ^W lnext ^V -ixon -ixoff"
eval spawn $argv

set timeout -1
expect -ex {Approve Request}
sleep 1
send "y\r"
expect eof

3. 补充说明

interact模式下,Expect会将子进程的pty与当前终端关联,并维持tty的交互模式属性(如规范模式、回显开启等);而expect eof模式下,子进程的pty默认处于非交互状态,程序X可能因检测不到终端交互信号而卡住。手动设置匹配interact的tty属性,即可让程序X在expect eof模式下正常执行并退出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:32:44