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
    echo $?

Suppose script.sh looks like this:

echo 'Before'
exit 1
echo 'After'

When I run that, I don't get


like I expected, but rather


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

echo $code

I get this:


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


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'
        echo "$?"

    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
        echo "\$?"

    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.


You must log in to answer this question.

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