我有简单的dockerfile
FROM alpine:latest
这是我的 docker run 命令
docker run <container-name> \
sh -c """set -eux pipefail && \
temp | sed 's/temp/perma/g'"""
这是输出
+ temp
sh: temp: not found
+ sed s/temp/perma/g
但是,上面 docker run 的返回码是 0。
即使我使用
set
出现管道故障,为什么 docker 返回 0?
虽然这里没有显示,但如果 sed 命令之后有任何与
&&
链接的后续命令,它们将被执行。
为什么
set -eux pipefail
不起作用?
请记住,Alpine 体积较小的原因之一是它不包含您通常在 Linux 上获得的完整 GNU 工具集,而是包含一个名为 BusyBox 的最小实现。当您使用 shell 时,您会获得 POSIX shell 规范 支持的内容,但仅此而已。
特别是,POSIX 标准 set(1) 不支持 bash 的
pipefail
选项。
如评论中所述,您还需要一个
-o
选项来指定长格式 shell 选项。如果没有 -o
,这会产生设置位置参数的效果。
$ docker run --rm alpine \
sh -c 'echo "one: $1"; set -eux pipefail; echo "one: $1"'
+ echo 'one: pipefail'
one:
one: pipefail
如果您确实需要扩展的 GNU bash 功能,则需要
apk add bash
安装 bash,或使用已包含该功能的基础映像,如 debian
或 ubuntu
。确保明确说出 bash -c
或 #!/bin/bash
,以便指定正确的 shell。