错误
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 build
sh
答案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'