“/bin/sh:1:MY_COMMAND:未找到”

“/bin/sh:1:MY_COMMAND:未找到”

错误

docker build -t MY_IMAGE_NAME .在为 ROS 项目使用 Dockerfile期间,在

RUN source /opt/ros/melodic/setup.bash

出现以下错误:

 => ERROR [stage-2 19/19] RUN source /opt/ros/melodic/setup.bash 
[...]
#23 0.404 /bin/sh: 1: source: not found
------ executor failed running [/bin/sh -c source /opt/ros/melodic/setup.bash]: exit code: 127

测试

为了测试这一点,我创建了错误步骤之前的步骤的图像,并检查了容器内的命令:并且它起作用了。因此,“source”命令在容器的 bash 中可用。那么,它怎么可能在图像中不可用呢?

docker run -dit --name MY_CONTAINER_NAME -v /opt/ros/melodic/ MY_IMAGE:latest
docker exec -it MY_CONTAINER_NAME /bin/bash

仅供参考:-v /opt/ros/melodic/挂载卷-v,否则/opt/ros/melodic/将为空。默认情况下,只有“构建上下文”(在本例中启动 Dockerfile 的地方)不为空。

现在在容器中,在 bash 中(使用上面加载/bin/bash):

root@1b2bdc5131sy:/# cd opt
root@1b2bdc5131sy:/opt# cd ros
root@1b2bdc5131sy:/opt/ros# ls
melodic
root@1b2bdc5131sy:/opt/ros# cd melodic
root@1b2bdc5131sy:/opt/ros/melodic# ls
_setup_util.py  env.sh  include  local_setup.bash  local_setup.zsh  setup.sh   share
bin             etc     lib      local_setup.sh    setup.bash       setup.zsh
root@1b2bdc5131sy:/opt/ros/melodic# ls
_setup_util.py  env.sh  include  local_setup.bash  local_setup.zsh  setup.sh   share
bin             etc     lib      local_setup.sh    setup.bash       setup.zsh

无论如何我都可以直接检查它,效果如下:

root@1b2bdc5131sy:/# source /opt/ros/melodic/setup.bash    

问题

由于“source”命令在容器MY_CONTAINER_NAME中工作,我怎样才能在Dockerfilebash期间让shell在底层映像MY_IMAGE_NAME中工作,而不是使用shell?docker buildsh

答案1

取自/bin/sh: 1: gvm: 未找到,大致意思是:

您的 shell 是 /bin/sh,但源需要 /bin/bash,可能是因为它将其初始化放在 中~/.bashrc

换句话说,该问题可能发生在任何使用“sh”shell 而不是“bash”的设置中,从而导致"/bin/sh: 1: MY_COMMAND: not found"

对于 Dockerfile,请使用推荐的

RUN /bin/bash -c 'source /opt/ros/melodic/setup.bash'

或者使用“ []”(我不想使用):

RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash"]

每次新的 bash RUN 都是独立的,“从 0 开始”。例如,请注意,在 Dockerfile 中 bash 命令之前的设置不会影响 bash 命令,因为必须在“.bashrc”中再次设置起始文件夹。即使您已经设置了 WORKDIR,也WORKDIR /MY_PROJECT需要这样做。cd /MY_PROJECT

附注:不要忘记“opt/../...”之前的第一个“/”。否则,它会抛出错误:

/bin/bash: opt/ros/melodic/setup.bash: No such file or directory

作品:

 => [stage-2 18/21] RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash"]                                  0.5s
 => [stage-2 19/21] [...]

您还可以将要执行的命令放在单个 bash 脚本中,然后在 Dockerfile 中运行该 bash 脚本(尽管我更愿意将 bash 命令也放在 Dockerfile 中,这只是我的观点):

#!/bin/bash
set -e

source /opt/ros/melodic/setup.bash

PS:你也可以将多个 bash 命令放在一行中:

RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash && MY_BASH_COMMAND && MY_BASH_COMMAND"]

或相同

RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash;MY_BASH_COMMAND;MY_BASH_COMMAND"]

或者在许多行中

RUN /bin/bash -c 'source /opt/ros/melodic/setup.bash &&\
    cd /MY_PROJECT &&\
    catkin_make -j8;\
    echo "source /MY_PROJECT/devel/setup.bash" >> ~/.bashrc'

或相同

RUN /bin/bash -c 'source /opt/ros/melodic/setup.bash;\
    cd /MY_PROJECT;\
    catkin_make -j8;\
    echo "source /MY_PROJECT/devel/setup.bash" >> ~/.bashrc'

请注意,使用RUN ["/bin/bash", "-c", "..."][]框架时,这只能在一行中起作用。至少我可以不(!)让它运行:

RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash && \
    cd /MY_PROJECT && \
    catkin_make -j8"]

也不与

RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash && 
    cd /MY_PROJECT && 
    catkin_make -j8"]

也不与

RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash; \
    cd /MY_PROJECT; \
    catkin_make -j8"]

也不与

RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash;
    cd /MY_PROJECT;
    catkin_make -j8"]

错误总是像这样:

executor failed running ... exit code: 127

PS2:您还可以将源命令添加到.bashrc(bash 启动时的“运行命令”),以便每次启动 bash 时都会加载该命令:

RUN ["/bin/bash", "-c", "echo 'source /MY_PROJECT/devel/setup.bash' >> ~/.bashrc"]

或者

RUN /bin/bash -c 'echo "source /MY_PROJECT/devel/setup.bash" >> ~/.bashrc'

相关内容