我在尝试捕获在 Docker 容器的 Heredoc 中运行的脚本的退出代码时陷入困境。
假设我想运行此命令来启动一个加载了 的 Docker 容器python:3.7
,并在其中执行一个heredoc。
docker run -v $PWD:/workspace -w /workspace --rm -i python:3.7 <<-EOF
./script.sh
echo $?
EOF
假设script.sh
看起来像这样:
echo 'Before'
exit 1
echo 'After'
当我运行它时,我没有得到
Before
1
正如我所料,但更确切地说
Before
0
当我尝试将退出代码分配给像这样的变量时
./script.sh
code=$?
echo $code
我明白了:
Before
script.sh
如何可靠地捕获在定界文档中运行的退出代码?
我想这首先与在定界文档中运行有关,因为在容器中直接运行相同的命令序列可以正常工作。
答案1
您的此处文档未加引号,这意味着调用 shell 将在将其传递给 之前扩展其中的变量docker
。
两种解决方案:
通过引用初始此处文档分隔符的任何部分来引用此处文档:
docker ... <<-'MY_SCRIPT' ./script.sh echo "$?" MY_SCRIPT
'MY_SCRIPT'
、"MY_SCRIPT"
、 或的任何变体\MY_SCRIPT
都可以工作(甚至'MY'_SCRIPT
等)。实际的分隔符应该是一个单词,并且通常以大写形式书写。我使用了一个词来额外描述重定向文档作为记录代码的一种方式。转义
$
重定向文档中的字符以阻止 shell 扩展该特定变量:docker ... <<-MY_SCRIPT ./script.sh echo "\$?" MY_SCRIPT
当此处文档包含需要由调用 shell 扩展的变量组合以及需要按原样传递的其他变量时,通常会使用此替代解决方案。