Bash 在带有';来源';不起作用

Bash 在带有';来源';不起作用,bash,shell,docker,Bash,Shell,Docker,我有一个Dockerfile,我正在组装它来安装一个普通的python环境(我将在其中安装一个应用程序,但稍后会安装) 构建运行正常,直到最后一行,在那里我得到以下异常: [previous steps 1-9 removed for clarity] ... Successfully installed virtualenvwrapper virtualenv-clone stevedore Cleaning up... ---> 1fc253a8f860 Step 10 : ENV

我有一个Dockerfile,我正在组装它来安装一个普通的python环境(我将在其中安装一个应用程序,但稍后会安装)

构建运行正常,直到最后一行,在那里我得到以下异常:

[previous steps 1-9 removed for clarity]
...
Successfully installed virtualenvwrapper virtualenv-clone stevedore
Cleaning up...
 ---> 1fc253a8f860
Step 10 : ENV WORKON_HOME ~/.virtualenvs
 ---> Running in 8b0145d2c80d
 ---> 0f91a5d96013
Step 11 : RUN mkdir -p $WORKON_HOME
 ---> Running in 9d2552712ddf
 ---> 3a87364c7b45
Step 12 : RUN source /usr/local/bin/virtualenvwrapper.sh
 ---> Running in c13a187261ec
/bin/sh: 1: source: not found
如果我
ls
进入该目录(只是为了测试前面的步骤是否已提交),我可以看到文件按预期存在:

$ docker run 3a87 ls /usr/local/bin
easy_install
easy_install-2.7
pip
pip-2.7
virtualenv
virtualenv-2.7
virtualenv-clone
virtualenvwrapper.sh
virtualenvwrapper_lazy.sh
如果我只是尝试运行
source
命令,我会得到与上面相同的“notfound”错误。但是,如果我运行交互式shell会话,则source可以工作:

$ docker run 3a87 bash
source
bash: line 1: source: filename argument required
source: usage: source filename [arguments]
我可以从这里运行脚本,然后愉快地访问
workon
mkvirtualenv

我做了一些挖掘,一开始看起来问题可能在于作为Ubuntu登录shell的bash和作为Ubuntu系统shell的dash之间的区别,dash不支持
源代码
命令

然而,答案似乎是使用'。而不是
源代码,但这只会导致Docker运行时爆发go panic异常


从Dockerfile运行指令运行shell脚本的最佳方法是什么(我运行的是Ubuntu12.04 LTS的默认基本映像)。

这可能是因为
source
是bash的内置程序,而不是文件系统中的二进制程序。您是否打算让您正在寻找的脚本在以后更改容器?

这可能是因为
source
是bash的内置组件,而不是文件系统中的二进制文件。您是否打算让您正在寻找的脚本在以后更改容器?

编辑:我的答案过时了。我认为另一个答案更好


运行/bin/bash-c“source/usr/local/bin/virtualenvwrapper.sh”

编辑:我的答案过时了。我认为另一个答案更好

运行/bin/bash-c“source/usr/local/bin/virtualenvwrapper.sh”

原始答案 这应该适用于每个Ubuntu docker基本映像。我通常为我编写的每个Dockerfile添加这一行

由关心的旁观者编辑 如果您想在整个Dockerfile中获得“使用
bash
而不是
sh
”的效果,而不改变可能损坏容器内的操作系统,您可以。就是这样做的:

SHELL ["/bin/bash", "-c"]
*可能的损害是,Linux中的许多脚本(在新安装的Ubuntu上
grep-rHInE'/bin/sh'/
返回超过2700个结果)希望在
/bin/sh
上使用完全的POSIX shell。bashshell不仅仅是POSIX加上额外的内置组件。有一些内置(以及更多)的行为与POSIX中的完全不同。我完全支持避免POSIX(以及一种谬论,即您没有在另一个shell上测试的任何脚本都会工作,因为您认为您避免了Basmism),而只是使用bashism。但你要在剧本中加入一个恰当的“shebang”。而不是从整个操作系统下拉出POSIX外壳。(除非您有时间验证Linux附带的所有2700多个脚本以及您安装的任何软件包中的所有脚本。)

更多细节请参见下面的回答

原始答案 这应该适用于每个Ubuntu docker基本映像。我通常为我编写的每个Dockerfile添加这一行

由关心的旁观者编辑 如果您想在整个Dockerfile中获得“使用
bash
而不是
sh
”的效果,而不改变可能损坏容器内的操作系统,您可以。就是这样做的:

SHELL ["/bin/bash", "-c"]
*可能的损害是,Linux中的许多脚本(在新安装的Ubuntu上
grep-rHInE'/bin/sh'/
返回超过2700个结果)希望在
/bin/sh
上使用完全的POSIX shell。bashshell不仅仅是POSIX加上额外的内置组件。有一些内置(以及更多)的行为与POSIX中的完全不同。我完全支持避免POSIX(以及一种谬论,即您没有在另一个shell上测试的任何脚本都会工作,因为您认为您避免了Basmism),而只是使用bashism。但你要在剧本中加入一个恰当的“shebang”。而不是从整个操作系统下拉出POSIX外壳。(除非您有时间验证Linux附带的所有2700多个脚本以及您安装的任何软件包中的所有脚本。)


更多细节请参见下面的回答

我也遇到了同样的问题,为了在virtualenv内部执行pip安装,我必须使用以下命令:

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh \
    && mkvirtualenv myapp \
    && workon myapp \
    && pip install -r /mycode/myapp/requirements.txt"

我希望它能有所帮助。

我也遇到了同样的问题,为了在virtualenv内部执行pip安装,我必须使用以下命令:

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh \
    && mkvirtualenv myapp \
    && workon myapp \
    && pip install -r /mycode/myapp/requirements.txt"

我希望它能有所帮助。

您可能需要运行
bash-v
来查看源代码

我将执行以下操作,而不是使用符号链接:


运行echo“source/usr/local/bin/virtualenvwrapper.sh”>/etc/bash.bashrc

您可能需要运行
bash-v
来查看源代码

我将执行以下操作,而不是使用符号链接:


运行echo“source/usr/local/bin/virtualenvwrapper.sh”>>/etc/bash.bashrc

基于本页的答案,我想补充一点,您必须知道,每个RUN语句都使用
/bin/sh-c
独立于其他语句运行,因此不会获得通常在登录shell中来源的任何环境变量

到目前为止,我找到的最好的方法是将脚本添加到
/etc/bash.bashrc
,然后作为bash登录调用每个命令

RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "your command"
例如,您可以安装和设置VirtualEnvRapper,创建虚拟环境,在使用bash登录时激活它,然后将python模块安装到此环境中:

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "mkvirtualenv myapp"
RUN echo "workon mpyapp" >> /etc/bash.bashrc
RUN /bin/bash --login -c "pip install ..."
阅读上的手册有助于了解什么是源代码。

在answ上构建
RUN source /usr/local/bin/virtualenvwrapper.sh
RUN . /usr/local/bin/virtualenvwrapper.sh
RUN cd ansible && source ./hacking/env-setup
RUN echo "source /ansible/hacking/env-setup" >> /tmp/setup
RUN /bin/bash -C "/tmp/setup"
RUN rm -f /tmp/setup
RUN ["/bin/bash", "-c", "echo hello"]
RUN "source file"      # translates to: RUN /bin/sh -c "source file"
SHELL ["/bin/bash", "-c"] 
RUN "source file"    # now translates to: RUN /bin/bash -c "source file"
SHELL ["/bin/bash", "-c"] 
SHELL ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]
SHELL ["executable", "parameters"]
FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello
...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...
# escape=`

FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
 ---> Running in 6fcdb6855ae2
 ---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
 ---> Running in d0eef8386e97


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       10/28/2016  11:26 AM                Example


 ---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
 ---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
 ---> Running in be6d8e63fe75
hello world
 ---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>
RUN ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]
# don't do this...
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh"
# because it is the same as this...
RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]
SHELL ["/bin/bash", "-c"]
SHELL ["/bin/bash", "-c", "-l"]

# Install ruby version specified in .ruby-version
RUN rvm install $(<.ruby-version)

# Install deps
RUN rvm use $(<.ruby-version) && gem install bundler && bundle install

CMD rvm use $(<.ruby-version) && ./myscript.rb
ENTRYPOINT ["bash", "--rcfile", "/usr/local/bin/virtualenvwrapper.sh", "-ci"]
## Conda with custom entrypoint from base ubuntu image
## Build with e.g. `docker build -t monoconda .`
## Run with `docker run --rm -it monoconda bash` to drop right into
## the environment `foo` !
FROM ubuntu:18.04

## Install things we need to install more things
RUN apt-get update -qq &&\
    apt-get install -qq curl wget git &&\
    apt-get install -qq --no-install-recommends \
        libssl-dev \
        software-properties-common \
    && rm -rf /var/lib/apt/lists/*

## Install miniconda
RUN wget -nv https://repo.anaconda.com/miniconda/Miniconda3-4.7.12-Linux-x86_64.sh -O ~/miniconda.sh && \
    /bin/bash ~/miniconda.sh -b -p /opt/conda && \
    rm ~/miniconda.sh && \
    /opt/conda/bin/conda clean -tipsy && \
    ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh

## add conda to the path so we can execute it by name
ENV PATH=/opt/conda/bin:$PATH

## Create /entry.sh which will be our new shell entry point. This performs actions to configure the environment
## before starting a new shell (which inherits the env).
## The exec is important! This allows signals to pass
RUN     (echo '#!/bin/bash' \
    &&   echo '__conda_setup="$(/opt/conda/bin/conda shell.bash hook 2> /dev/null)"' \
    &&   echo 'eval "$__conda_setup"' \
    &&   echo 'conda activate "${CONDA_TARGET_ENV:-base}"' \
    &&   echo '>&2 echo "ENTRYPOINT: CONDA_DEFAULT_ENV=${CONDA_DEFAULT_ENV}"' \
    &&   echo 'exec "$@"'\
        ) >> /entry.sh && chmod +x /entry.sh

## Tell the docker build process to use this for RUN.
## The default shell on Linux is ["/bin/sh", "-c"], and on Windows is ["cmd", "/S", "/C"]
SHELL ["/entry.sh", "/bin/bash", "-c"]
## Now, every following invocation of RUN will start with the entry script
RUN     conda update conda -y

## Create a dummy env
RUN     conda create --name foo

## I added this variable such that I have the entry script activate a specific env
ENV CONDA_TARGET_ENV=foo

## This will get installed in the env foo since it gets activated at the start of the RUN stanza
RUN  conda install pip

## Configure .bashrc to drop into a conda env and immediately activate our TARGET env
RUN conda init && echo 'conda activate "${CONDA_TARGET_ENV:-base}"' >>  ~/.bashrc
ENTRYPOINT ["/entry.sh"]
[mlazo@srvjenkins project_textile]$ cat docker/Dockerfile.debug 
FROM malazo/project_textile_ubuntu:latest 

ENV PROJECT_DIR=/proyectos/project_textile PROJECT_NAME=project_textile WRAPPER_PATH=/usr/share/virtualenvwrapper/virtualenvwrapper.sh

COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}

RUN echo "source ${WRAPPER_PATH}" > ~/.bashrc
SHELL ["/bin/bash","-c","-l"]
RUN     mkvirtualenv -p $(which python3) ${PROJECT_NAME} && \
        workon ${PROJECT_NAME} && \
        pip3 install -r requirements.txt 

EXPOSE 8000

ENTRYPOINT ["tests/container_entrypoint.sh"]
CMD ["public/manage.py","runserver","0:8000"]

[mlazo@srvjenkins project_textile]$ cat tests/container_entrypoint.sh
#!/bin/bash
# *-* encoding : UTF-8 *-*
sh tests/deliver_env.sh
source ~/.virtualenvs/project_textile/bin/activate 
exec python "$@"

[mlazo@srvjenkins project_textile]$ cat ./tests/container_deployment.sh 
#!/bin/bash

CONT_NAME="cont_app_server"
IMG_NAME="malazo/project_textile_app"
[ $(docker ps -a |grep -i ${CONT_NAME} |wc -l) -gt 0 ] && docker rm -f ${CONT_NAME} 
docker run --name ${CONT_NAME} -p 8000:8000 -e DEBUG=${DEBUG} -e MYSQL_USER=${MYSQL_USER} -e MYSQL_PASSWORD=${MYSQL_PASSWORD} -e MYSQL_HOST=${MYSQL_HOST} -e MYSQL_DATABASE=${MYSQL_DATABASE} -e MYSQL_PORT=${MYSQL_PORT}  -d ${IMG_NAME}