So this annoying and trivial little problem catches me out every so often. I am always misled by the error message! You’ll see what I mean shortly. For context, it usually happens when I’m working in Docker containers on a build.
Let’s say we have a script like this, saved as
#!/bin/bash echo "Hello, Bash"
Nice and simple. Let’s build a Docker image with it that runs it. Here’s the Dockerfile.
FROM alpine COPY bash-script.sh . RUN ./bash-script.sh
Let’s build and see what happens:
$ podman build -f bash.Dockerfile . STEP 1: FROM alpine STEP 2: COPY bash-script.sh . --> 01a74a697df STEP 3: RUN ./bash-script.sh /bin/sh: ./bash-script.sh: not found Error: error building at STEP "RUN ./bash-script.sh": error while running runtime: exit status 127
Aww, snap! The script has to be there, we just copied it into place. So why do we get an error saying that
./bash-script.sh is not found?
The answer is… because we’re trying to run a Bash script on an Alpine image. Alpine doesn’t ship with a Bash shell, so the error is really saying that the interpreter
/bin/bash isn’t found, not that the script itself isn’t found. Catches me out every time!
#!/bin/sh instead. Might need to avoid any Bash-specific syntax. Given this script saved as
#!/bin/sh echo "Hello, Shell"
Add in an adjusted Dockerfile to pick up the new script instead:
FROM alpine COPY sh-script.sh . RUN ./sh-script.sh
Building, we get:
$ podman build -f sh.Dockerfile . STEP 1: FROM alpine STEP 2: COPY sh-script.sh . --> d82ae1d0b10 STEP 3: RUN ./sh-script.sh Hello, Shell STEP 4: COMMIT --> 8fa27f213ed
We’re all good. The
#!/bin/sh directive should attempt to use a compatible shell rather than requiring Bash specifically.