无--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
相关产品推荐
相关产品推荐

