无法在 Dockerfile 中使用 *运行* 执行 *catkin* 命令

Unable to execute *catkin* commands using *RUN* in Dockerfile

我想在 docker 上使用自定义的 ros-indigo。我准备了以下 Dockerfile

FROM ros:indigo-robot

RUN echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
RUN mkdir -p /home/catkin_ws/src
WORKDIR /home/catkin_ws/src
RUN catkin_init_workspace
WORKDIR /home/catkin_ws
RUN catkin_make
RUN echo "source /home/catkin_ws/devel/setup.bash" >> ~/.bashrc

但是,它在 运行 catkin_init_workspace运行 catkin_make 都抛出了一个错误

/bin/sh: catkin_make: command not found
The command '/bin/sh -c catkin_init_workspace' returned a non-zero code: 127

令人惊讶的是,如果我将 运行 更改为 CMD for catkin[=36,它会成功构建=] 命令,即以下 Dockerfile 构建得很好

RUN echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
RUN mkdir -p /home/catkin_ws/src
WORKDIR /home/catkin_ws/src
CMD catkin_init_workspace
WORKDIR /home/catkin_ws
CMD catkin_make
RUN echo "source /home/catkin_ws/devel/setup.bash" >> ~/.bashrc

更令人惊讶的是,这些柔荑花序命令在单独构建在任何 ros-indigo 图像之上的容器上完美运行。

这清楚地表明 运行 不是调用 catkin 命令的合适方式,或者我调用不正确.

现在,考虑到 CMD 命令的性质不同于 运行 命令,它没有意义在我的情况下使用它。因此,如果有人能指出正确的方法,我将不胜感激。

您的第二个案例将会生成,因为 CMD 在生成期间未执行。它只是定义了启动容器时要执行的默认命令。有关详细信息,请参阅 docker CMD docs

问题的根源在于 ~/.bashrc 未在 RUN 指令使用的 shell 中调用。结果,环境变量不存在以允许 catkin_make 或其他 ros 命令工作。我通过 运行 类似于下面的命令解决了图像中的这个问题。

RUN . /opt/ros/kinetic/setup.sh && \
    catkin_make

您需要在每个需要这些环境变量的 RUN 指令中激活环境,因为 shell 不会在 RUN 命令之间重复使用。

编辑以包括 David Maze 的改进。

您需要设置适当的 bash 环境才能使命令正常工作(默认情况下 Docker 使用 sh 来执行命令)。这些命令对我有用:

FROM ros:indigo-robot

RUN echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
RUN mkdir -p /home/catkin_ws/src
WORKDIR /home/catkin_ws/src
#RUN /opt/ros/indigo/bin/catkin_init_workspace
RUN /bin/bash -c '. /opt/ros/indigo/setup.bash; catkin_init_workspace /home/catkin_ws/src'

WORKDIR /home/catkin_ws
RUN /bin/bash -c '. /opt/ros/indigo/setup.bash; cd /home/catkin_ws; catkin_make'
RUN echo "source /home/catkin_ws/devel/setup.bash" >> ~/.bashrc