I have simple dockerfile
FROM alpine:latest
This is my docker run command
docker run <container-name> \
sh -c """set -eux pipefail && \
temp | sed 's/temp/perma/g'"""
This is the output
+ temp
sh: temp: not found
+ sed s/temp/perma/g
But, the return code of the above docker run is 0.
Even though I have a pipefail using set
, why does docker return 0?
Though not shown here, if there were any subsequent commands after the sed command which were chained with &&
, they will be executed.
Why does set -eux pipefail
not work ?
Remember that one of the things that makes Alpine small is that it doesn't include the full GNU tool set you normally get on Linux, but instead a minimal implementation called BusyBox. When you're using the shell, you get what's supported in the POSIX shell specification but not much more.
In particular, POSIX-standard set(1) doesn't support bash's pipefail
option.
As noted in a comment, you also need a -o
option to specify long-form shell options. Without -o
, this has the effect of setting positional arguments instead.
$ docker run --rm alpine \
sh -c 'echo "one: $1"; set -eux pipefail; echo "one: $1"'
+ echo 'one: pipefail'
one:
one: pipefail
If you really need extended GNU bash functionality, you need to apk add bash
to install bash, or to use a base image like debian
or ubuntu
that already includes it. Make sure to explicitly say bash -c
or #!/bin/bash
so you're specifying the right shell.