【问题标题】:Dockerfile creates a file and then it's not thereDockerfile 创建一个文件,然后它不存在
【发布时间】:2019-06-23 18:23:21
【问题描述】:

这只是一个令我困惑的 Dockefile 的一部分。顺便说一句,它有一些额外的调试行。在第一行中,我创建了 /home/ubuntu/.bashrc。然而,在最后一行,它的行为就好像它无法运行一样。

RUN echo 'source /opt/ros/kinetic/setup.bash' >> /home/ubuntu/.bashrc
RUN echo 'source /home/ubuntu/catkin_ws/devel/setup.bash' >> /home/ubuntu/.bashrc

RUN /bin/bash -c "echo 'export HOME=/home/ubuntu' >> /root/.bashrc && source /root/.bashrc"
RUN pwd
RUN cd ~ && pwd
RUN cat /home/ubuntu/.bashrc
RUN mkdir -p ~/catkin_ws/src
RUN source /home/ubuntu/.bashrc && \
  cd ~/catkin_ws/src && \
  /opt/ros/kinetic/bin/catkin_init_workspace && \
  cd ~/catkin_ws && \
  catkin_make

这是输出:

Step 13/32 : RUN echo 'source /opt/ros/kinetic/setup.bash' >> /home/ubuntu/.bashrc
 ---> Using cache
 ---> a60c2d1482d8
Step 14/32 : RUN echo 'source /home/ubuntu/catkin_ws/devel/setup.bash' >> /home/ubuntu/.bashrc
 ---> Using cache
 ---> 3be964ee0c36
Step 15/32 : RUN /bin/bash -c "echo 'export HOME=/home/ubuntu' >> /root/.bashrc && source /root/.bashrc"
 ---> Using cache
 ---> 83cf2e5f4b1c
Step 16/32 : RUN pwd
 ---> Using cache
 ---> 40915ecc834d
Step 17/32 : RUN cd ~ && pwd
 ---> Using cache
 ---> 92f2cee78a48
Step 18/32 : RUN cat /home/ubuntu/.bashrc
 ---> Using cache
 ---> c8f467775b33
Step 19/32 : RUN mkdir -p ~/catkin_ws/src
 ---> Using cache
 ---> 53e5c403949f
Step 20/32 : RUN source /home/ubuntu/.bashrc &&   cd ~/catkin_ws/src &&   /opt/ros/kinetic/bin/catkin_init_workspace &&   cd ~/catkin_ws &&   catkin_make
 ---> Running in 708d485325e2
/bin/sh: 1: source: not found
The command '/bin/sh -c source /home/ubuntu/.bashrc &&   cd ~/catkin_ws/src &&   /opt/ros/kinetic/bin/catkin_init_workspace &&   cd ~/catkin_ws &&   catkin_make' returned a non-zero code: 127

当然,这是我的错误,但我看不到它,也看不到我理解上的差距。谢谢!

【问题讨论】:

标签: docker


【解决方案1】:

source 不是一个有效的命令,它是一个内置的 bash。

不是告诉你文件/home/ubuntu/.bashrc而是source不是命令

只需将 RUN 参数放入 sh 脚本中,并以 #!/bin/bash 正确启动。 然后使用 COPY 将 sh 复制到容器中,然后使用 RUN 运行它。

别忘了给脚本 exec 权限:

COPY script.sh /
RUN ["chmod", "+x", "/script.sh"]
RUN /script.sh

或者:

RUN /bin/bash -c "source ...."

【讨论】:

  • @pitosalas。 E 编辑了您问题的答案。请等待迈克尔批准。
  • 这带来了另一件让我困惑的小事:COPY 究竟是从哪里复制的?我假设它正在复制到容器的根目录。
  • @pitosalas, COPY from_source_folder to_container_folder,所以这会将与 Dockerfile 位于同一目录中的 script.sh 文件复制到容器的根文件夹(/)。但是您可以更改这两个参数,例如: COPY src/script.sh /usr/local/bin/ ,这个从 src 文件夹复制到 usr/local/bin
【解决方案2】:

正如@michael_bitard 所指出的,source 是内置的 bash。 ubuntu 中的默认 shell 是 dash,如下所示:

# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 22 17:49 /bin/sh -> dash

要使用bash 运行命令,请将RUN 指令更改为

RUN cd ~/catkin_ws/src && \
  /opt/ros/kinetic/bin/catkin_init_workspace && \
  cd ~/catkin_ws && \
  /bin/bash -c "source /home/ubuntu/.bashrc; catkin_make"

另一个选项是设置BASH_ENV 环境变量,它应该在运行catkin_make 之前提到的here 的bash 脚本之前获取指定文件(/home/ubuntu/.bashrc)。

ENV BASH_ENV /home/ubuntu/.bashrc
RUN cd ~/catkin_ws/src && \
  /opt/ros/kinetic/bin/catkin_init_workspace && \
  cd ~/catkin_ws && \
  /bin/bash -c "catkin_make"

【讨论】:

  • 哇!我假设我没有编写 shell 脚本,它是用于 bash,所以 dash 不能运行它?或者有没有办法只使用破折号? (2) 此外,当您说“另一个选项”时,您的意思是我可以在您的示例运行 catkin make 的地方添加一个 -i ,只需 -c 对吗?
  • 尝试您的建议,这是什么意思:步骤 17/30:运行 cd ~/catkin_ws/src && /bin/bash -c -i "catkin_init_workspace" ---> 在 e16b435a0439 bash 中运行:无法设置终端进程组(1):设备 bash 的 ioctl 不合适:此 shell bash 中没有作业控制:/home/ubuntu/catkin_ws/devel/setup.bash:没有这样的文件或目录
  • @pitosalas 是的。如果脚本是为 bash 创建的,如果脚本使用特定的 bash 功能,它很可能与 dash 不兼容。
  • 我猜 bash 不能在 Dockerfile 指令中以交互方式运行(bash 与 -i)。我已将其从答案中删除并添加了另一个替代选项。希望这会有所帮助!
  • 由于某种原因,脚本作者有 ifs 在里面检查它是否以交互方式运行,如果不是,则跳过重要步骤。不知道他们为什么这样做,但是,有没有办法让其他人编写的脚本认为它是交互式运行的?
猜你喜欢
  • 1970-01-01
  • 2015-11-12
  • 2012-10-26
  • 2022-12-09
  • 2012-06-26
  • 2013-12-07
  • 2017-11-26
  • 2016-03-01
  • 2016-03-17
相关资源
最近更新 更多