程序启动后能否使用输入重定向?利用自身输出构造输入的场景
嘿,这个需求太典型了——你需要和程序做交互式的输入输出联动:先捕获它的输出内容,再用这个内容构造后续的输入发回去对吧?我给你几个实用的方案,按需选就行:
方法1:用expect脚本(最适合交互式场景)
expect是专门用来处理这类交互式程序的工具,语法很直观,能精准匹配程序输出并发送对应输入。
写个示例脚本(比如叫interact_with_binary.exp):
#!/usr/bin/expect # 启动你的二进制程序 spawn ./Binary # 等待程序输出包含目标内容的行(对应你说的步骤2输出) expect "Hello the open machine is:" # 提取输出里的"computer2"——这里按冒号分割,取最后一段并去掉空格 set machine [string trim [lindex [split $expect_out(buffer) ":"] end]] # 发送构造好的输入,记得加回车符\r send "$machine:RunWaterPlants\r" # 如果之后还要继续交互,就用interact;要是想等程序结束,就用wait interact
使用步骤:
- 给脚本加执行权限:
chmod +x interact_with_binary.exp - 直接运行:
./interact_with_binary.exp
方法2:纯Bash用coproc(协同进程)
如果不想装额外工具,Bash自带的coproc能帮你实现进程间的输入输出交互:
示例脚本(bash_interact.sh):
#!/bin/bash # 启动协同进程,把程序的stdin/stdout绑定到文件描述符 coproc ./Binary # 循环读取程序的输出,直到找到目标内容 while IFS= read -r line; do echo "[程序输出] $line" # 检查行里是否包含我们要提取的关键词 if [[ "$line" == *"computer2"* ]]; then # 用awk分割提取机器名(根据实际输出格式调整分割符) machine=$(echo "$line" | awk -F': ' '{print $2}') # 把构造好的输入发送给程序的stdin echo "$machine:RunWaterPlants" >&${COPROC[1]} break fi done <&${COPROC[0]} # 等待程序结束 wait $COPROC_PID
注意:如果程序输出有缓冲导致脚本读不到实时内容,可以用stdbuf关闭缓冲,把启动命令改成:coproc stdbuf -i0 -o0 ./Binary
方法3:用命名管道(mkfifo)
通过创建两个命名管道,把程序的输入输出和脚本连接起来,适合更复杂的场景:
#!/bin/bash # 创建两个命名管道 mkfifo program_in program_out # 启动程序,将stdin绑定到program_in,stdout绑定到program_out ./Binary < program_in > program_out & # 读取程序输出 while IFS= read -r line < program_out; do echo "[程序输出] $line" if [[ "$line" == *"computer2"* ]]; then machine=$(echo "$line" | awk -F': ' '{print $2}') echo "$machine:RunWaterPlants" > program_in break fi done # 清理管道 rm program_in program_out wait
小提示
- 提取字符串的逻辑要根据程序的实际输出格式调整,比如如果输出不是
Hello the open machine is: computer2,你得改awk/split的规则; - 要是程序的输出有行缓冲,记得用
stdbuf或者unbuffer工具强制无缓冲输出,不然脚本会一直卡着等缓冲区满。
内容的提问来源于stack exchange,提问作者Corey
相关产品推荐
相关产品推荐

