0

I was playing around and got stuck while trying to capture the exit code of a script I'm running within a heredoc in a Docker container.

Say I want to run this command to start a Docker container loaded with python:3.7, and execute a heredoc inside of it.

docker run -v $PWD:/workspace -w /workspace --rm -i python:3.7 <<-EOF
    ./script.sh
    echo $?
EOF

Suppose script.sh looks like this:

echo 'Before'
exit 1
echo 'After'

When I run that, I don't get

Before
1

like I expected, but rather

Before
0

When I try to assign the exit code to a variable like

./script.sh
code=$?
echo $code

I get this:

Before

How can I reliably capture the exit code of script.sh which is run within a heredoc?


I imagine it has something to do with it running in a heredoc in the first place, as running that same sequence of commands within the container directly works fine.

1 Answer 1

2

Your here-document is not quoted, which means that the invoking shell will expand variables within it before passing it to docker.

Two solutions:

  1. Quote the here-document by quoting any part of the initial here-document delimiter:

    docker ... <<-'MY_SCRIPT'
        ./script.sh
        echo "$?"
    MY_SCRIPT
    

    Any variant of 'MY_SCRIPT', "MY_SCRIPT", or \MY_SCRIPT would work (even 'MY'_SCRIPT etc.) The actual delimiter should be a word and is usually written in upper-case. I've used a word that additionally describes the redirected document as a way of documenting the code.

  2. Escape the $ character within the redirected document to stop the shell from expanding that particular variable:

    docker ... <<-MY_SCRIPT
        ./script.sh
        echo "\$?"
    MY_SCRIPT
    

    This alternative solution is often used when the here-document contains a combination of variables that need to be expanded by the invoking shell and others that need to be passed as is.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .