skip to Main Content

I’m trying to source .bashrc but no luck

USER user
SHELL ["/bin/bash", "-c"]
RUN echo "export TEST_VAR=test" >> /home/user/.bashrc && tail /home/user/.bashrc && source /home/user/.bashrc && echo "1 "${TEST_VAR} 2" var" && exit 1

I expect that this RUN command print 1 "test" 2 but what i get is that

Step 13/40 : RUN echo "export TEST_VAR=test" >> /home/user/.bashrc && tail /home/user/.bashrc && source /home/user/.bashrc && echo "1 "${TEST_VAR}" 2" && exit 1
 ---> Running in b870d36e9dd0
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi
export TEST_VAR=test
1 "" 2

What’s wrong with handling shells in docker? I just wanted to source ~/.bashrc once and use all exposed variables in subsequent command below source call but it doesn’t even work in a single subshell joined with &&

2

Answers


  1. Usually ~/.bashrc contains something similar to:

    # If not running interactively, don't do anything
    case $- in
        *i*) ;;
          *) return;;
    esac
    

    That is very normal – .bashrc is meant to be used in interactive sessions only. Because RUN is non-interactive, it just exits.

    Aaaanyway, I would recommend, if you want to only add environment variables, output them to /etc/profile.d and . /etc/profile.

    Login or Signup to reply.
  2. Most paths in Docker don’t read shell dotfiles at all. You need to use other approaches to provide configuration to your application; for example, Dockerfile ENV to set environment variables or an entrypoint wrapper script if you need things to be set up dynamically before starting the container.

    Let’s look specifically at a reduced form of your example:

    SHELL ["/bin/bash", "-c"]
    RUN echo "export TEST_VAR=test" >> $HOME/.bashrc
    RUN echo "$TEST_VAR"
    

    Bash Startup Files in the GNU Bash manual lists out which dotfiles are read in which case. For the last line Docker combines the SHELL and RUN lines to run the equivalent of

    /bin/bash -c 'echo "$TEST_VAR"'
    

    but the bash instance is neither an interactive nor a login shell, so the only dotfile that’s automatically read is one named in a $BASH_ENV environment variable. (POSIX sh doesn’t specify anything about any shell dotfiles at all.)

    This further applies to the image’s default CMD, which also will get run with sh -c (or the alternate SHELL) and it won’t read dotfiles. If the CMD (or ENTRYPOINT or RUN) uses JSON-array syntax, it won’t invoke a shell at all, and again won’t read dotfiles.

    The only case where shell dotfiles will be read is if the main container command is an interactive shell, and this won’t typically be the common case.

    docker run --rm -it yourimage /bin/bash         # reads .bashrc
    docker run --rm -it yourimage /bin/bash --login # also reads .profile, .bash_login
    

    This means you should almost never try to edit the .bashrc, /etc/profile, or any similar files. If you need to set environment variables as in the example, use Dockerfile ENV instead.

    ENV TEST_VAR=test
    RUN echo "$TEST_VAR"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search