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

无--interactive参数运行Docker容器时expect脚本执行失败排查

Docker容器中Expect脚本使用expect_before时的stdout错误问题

问题复现过程

1. 创建Expect脚本 test.expect

初始状态下expect_before处于注释状态:

#!/usr/bin/expect -f 

set timeout 3
#expect_before timeout { puts "\nTimeout fired"; exit 1 }

puts "--- Start"
lassign $argv name duration

spawn bash -c "echo Hello ${name} && sleep ${duration} "
expect {
    eof {
        puts "No timeout";
    }
}
puts "--- End"

2. 编写Docker镜像的Dockerfile

FROM alpine:latest

RUN apk update && \
    apk upgrade && \
    apk add bash expect

COPY test.expect /root
ENV PATH $PATH:/root

WORKDIR /root
ENTRYPOINT ["test.expect"]

3. 初始构建与运行(expect_before注释)

构建镜像并运行容器,无论是否使用-i(交互式)参数,脚本均正常执行:

$ docker build -t test-expect .
$ docker run -i test-expect Martin 2
--- Start
spawn bash -c echo Hello Martin && sleep 2
Hello Martin
No timeout
--- End
$ docker run -i test-expect Martin 5
--- Start
spawn bash -c echo Hello Martin && sleep 5
Hello Martin
--- End
$ docker run test-expect Martin 2
--- Start
spawn bash -c echo Hello Martin && sleep 2
Hello Martin
No timeout
--- End
$ docker run test-expect Martin 5
--- Start
spawn bash -c echo Hello Martin && sleep 5
Hello Martin
--- End

4. 启用expect_before后的异常表现

取消expect_before的注释,重新构建镜像后运行:

$ docker build -t test-expect .
$ docker run -i test-expect Martin 2
--- Start
spawn bash -c echo Hello Martin && sleep 2
Hello Martin
No timeout
--- End
$ docker run -i test-expect Martin 5
--- Start
spawn bash -c echo Hello Martin && sleep 5
Hello Martin

Timeout fired
$ docker run test-expect Martin 2
--- Start
spawn bash -c echo Hello Martin && sleep 2
error writing "stdout": bad file number
    while executing
"puts "--- End""
    (file "/root/test.expect" line 15)
$ docker run test-expect Martin 5
--- Start
spawn bash -c echo Hello Martin && sleep 5
error writing "stdout": bad file number
    while executing
"puts "--- End""
    (file "/root/test.expect" line 15)

可以看到,使用-i参数时脚本仍正常工作,但不使用-i参数时,无论是否触发超时,都会出现error writing "stdout": bad file number错误。

5. 调试信息

使用expect -d调试未获得有效线索:

$ docker run test-expect Martin 5
expect version 5.45.4
argv[0] = /usr/bin/expect  argv[1] = -df  argv[2] = /root/test.expect  argv[3] = Martin  argv[4] = 5
set argc 2
set argv0 "/root/test.expect"
set argv "Martin 5"
executing commands from command file /root/test.expect
--- Start
spawn bash -c echo Hello Martin && sleep 5
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {7}
expect: read eof
expect: set expect_out(spawn_id) "exp0"
expect: set expect_out(buffer) ""
error writing "stdout": bad file number
    while executing
"puts "--- End""
    (file "/root/test.expect" line 15)

问题疑问

最初在GitHub workflows流水线中遇到该问题时,曾误以为是环境无stdin/stdout导致,但通过简化测试用例发现是expect_before引发此问题。目前无法理解expect_before导致该行为的原因,也不知道如何修复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:07:49