bash 为什么运行docker容器时不执行`~/.bashrc`?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/55206227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why `~/.bashrc` is not executed when run docker container?
提问by Joey Yi Zhao
I have a docker file as below. launch.sh
is the entry point in this docker image.
我有一个 docker 文件,如下所示。launch.sh
是这个 docker 镜像的入口点。
FROM ubuntu:16.04
USER root
RUN apt-get update && apt-get install -y \
curl \
vim \
net-tools \
git \
iputils-ping \
wget
RUN apt-get install -y python
RUN apt-get update && apt-get install -y gcc g++ make libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
ENV NVM_DIR /root/.nvm
RUN . $NVM_DIR/nvm.sh && \
nvm install 7.9.0 && npm install -g [email protected]
ADD ./Docker/launch.sh /workspace/
CMD ["/bin/sh", "/workspace/launch.sh"]
The content of launch.sh
is:
内容launch.sh
为:
#!/bin/bash
cd /workspace/demo
npm install
node index.js
when I run the docker container: docker run IMAGE_NAME
, I got this error:
当我运行 docker container: 时docker run IMAGE_NAME
,出现此错误:
npm: not found
node: not found
The node
in this image is managed by nvm
which has been installed and its script has been set on /root/.bashrc
file. But I don't know why it can't find the nodejs commands. But if I run the container by docker run -it IMAGE_NAME bash
, then manually run workspace/launch.sh
command, everything works fine. It seems the ~/.bashrc
is not executed when run the image. How can I let the container source .bashrc?
在node
此图像中设法通过nvm
已安装和脚本的设置/root/.bashrc
文件。但是我不知道为什么它找不到nodejs命令。但是如果我通过 运行容器docker run -it IMAGE_NAME bash
,然后手动运行workspace/launch.sh
命令,一切正常。~/.bashrc
运行图像时似乎没有执行。我怎样才能让容器来源 .bashrc?
The content of /root/.bashrc
is:
内容/root/.bashrc
为:
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
# don't put duplicate lines in the history. See bash(1) for more options
# ... or force ignoredups and ignorespace
HISTCONTROL=ignoredups:ignorespace
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[3[01;32m\]\u@\h\[3[00m\]:\[3[01;34m\]\w\[3[00m\]$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
#if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
# . /etc/bash_completion
#fi
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
采纳答案by Szymon Maszke
Each command runs a separate sub-shell, so the environment variables are not preserved and .bashrc
is not sourced (see this answer).
每个命令都运行一个单独的子 shell,因此环境变量不会被保留并且.bashrc
没有来源(请参阅此答案)。
You have to source your script manually in the same processwhere you run your command so it would be:
您必须在运行命令的同一过程中手动获取脚本,因此它将是:
CMD source /root/.bashrc && /workspace/launch.sh
provided your launch.sh
is an executable.
前提launch.sh
是你是一个可执行文件。
As per documentationexec
form you are using does not invoke a command shell, so it won't work with your .bashrc
.
根据您使用的文档exec
形式不会调用命令外壳,因此它不适用于您的.bashrc
.
Edit:
编辑:
BASH wasn't your default shell so
BASH 不是你的默认 shell,所以
CMD /bin/bash -c "source /root/.bashrc && /workspace/launch.sh"
was needed in order to run your script.
If you want yo set your shell as BASH by default, you can use SHELL
instruction as described in documentation, e.g.:
需要运行您的脚本。如果您希望默认情况下将 shell 设置为 BASH,您可以使用文档中SHELL
描述的指令,例如:
SHELL ["/bin/bash", "-c"]
回答by Mostafa Hussein
You can add source /path/to/bashrc
in launch.sh
and change the CMD
to the following instead of changing to bash through CMD
itself:
您可以添加source /path/to/bashrc
在launch.sh
并更改CMD
为以下,而不是通过改变来砸CMD
自己:
CMD ["/workspace/launch.sh"]
Alternatively, You can do the following in your Dockerfile instead of depending on bashrc
或者,您可以在 Dockerfile 中执行以下操作,而不是依赖于 bashrc
ENV NVM_DIR /root/.nvm
ENV NODE_VERSION 7.9.0
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules #Ensure that this is the actual path
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN . $NVM_DIR/nvm.sh && \
nvm install $NODE_VERSION && npm install -g [email protected]