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

如何在Expect中与多个并发生成的spawn进程交互?

解决Expect多进程同时交互的问题

首先明确:Expect里根本没有expect_background这个命令,你要实现多进程并行交互,得靠多spawn实例+多分支expect监听+定向操作来实现。下面给你一套可运行的方案,解决你遇到的interact: spawn id exp5 not open报错问题。

先准备两个测试用的Shell脚本

t1.sh

#!/bin/bash
while true; do
    echo "[T1] 请输入命令:"
    read input
    echo "[T1] 你输入了:$input"
    sleep 1
done

t2.sh

#!/bin/bash
while true; do
    echo "[T2] 请输入指令:"
    read input
    echo "[T2] 收到指令:$input"
    sleep 1
done

核心Expect脚本 ex1.ex

这个脚本会同时启动两个进程,监听它们的输出,并支持你定向给指定进程发命令,避免交互混乱:

#!/usr/bin/expect -f

# 启动两个进程并保存各自的spawn ID
set t1 [spawn ./t1.sh]
set t2 [spawn ./t2.sh]

# 设置超时时间为无限,避免进程超时退出
set timeout -1

# 循环监听两个进程的输出,同时处理用户输入
proc interact_with_procs {t1 t2} {
    while {1} {
        expect {
            # 匹配T1的输出提示
            "\[T1\] 请输入命令:" {
                # 允许用户输入并发送给T1
                send_user "\n输入给T1的内容:"
                expect_user -re "(.*)\n"
                send $t1 "$expect_out(1,string)\r"
                exp_continue
            }
            # 匹配T2的输出提示
            "\[T2\] 请输入指令:" {
                # 允许用户输入并发送给T2
                send_user "\n输入给T2的内容:"
                expect_user -re "(.*)\n"
                send $t2 "$expect_out(1,string)\r"
                exp_continue
            }
            # 处理进程退出的情况,避免报错
            eof {
                set current_spawn $expect_out(spawn_id)
                if {$current_spawn eq $t1} {
                    send_user "\n[T1] 进程已退出\n"
                } else {
                    send_user "\n[T2] 进程已退出\n"
                }
                # 可以选择退出脚本或者继续监听另一个进程
                # exit
            }
        }
    }
}

# 调用交互函数
interact_with_procs $t1 $t2

关键说明

  1. 保存spawn ID:每个spawn命令返回的ID必须存在变量里,后续操作(send/expect)都要指定这个ID,否则会默认操作最后一个spawn的进程,导致混乱。
  2. 多分支expect监听:用expect的多条件匹配,同时监听两个进程的输出,匹配到对应提示后再处理用户输入,定向发送到目标进程。
  3. 避免spawn id报错:
    • 确保进程没有提前退出:如果你的Shell脚本是一次性执行的,运行完就会退出,Expect再操作就会报spawn id not open,所以测试脚本要用while true保持存活。
    • 处理eof事件:当某个进程退出时,捕获这个事件并提示,避免脚本崩溃。
  4. 替代interact的定向操作:直接用expect_user捕获用户输入,再用send $spawn_id "内容\r"定向发送,比原生interact更灵活,适合多进程场景。

运行方式

  1. 给三个脚本加执行权限:chmod +x ex1.ex t1.sh t2.sh
  2. 运行Expect脚本:./ex1.ex

这样就能同时和两个进程交互,输入内容时会提示你是发给T1还是T2,不会出现交互混乱或报错的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:04:58