0

This is just a piece of a Dockefile that's confusing me. It has some extra debugging lines in it by the way. In the first line I create /home/ubuntu/.bashrc. However then at the last line, it acts as if it cannot run it.

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

Here's the output:

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

Naturally, it's my bug but I cant see it nor the gap in my understanding.Thanks!

pitosalas
  • 10,286
  • 12
  • 72
  • 120

2 Answers2

1

source is not a valid command, it's a bash builtin.

It's not telling you that the file /home/ubuntu/.bashrc but that source is not a command

Just put the RUN parameter in a sh script, started correctly with #!/bin/bash. Then just copy the sh to the container using COPY, and run it with RUN.

Don't forget to give the exec permission to the script:

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

Or:

RUN /bin/bash -c "source ...."
andre-lx
  • 312
  • 3
  • 14
michael_bitard
  • 3,613
  • 1
  • 24
  • 35
  • 1
    @pitosalas. E edited the answer to your question. Please wait for Michael to approve. – andre-lx Jan 30 '19 at 13:34
  • That brings up another little thing that confused me: where is that COPY copying from exactly? I assume it is copying to the root of the container. – pitosalas Jan 31 '19 at 01:35
  • @pitosalas, COPY from_source_folder to_container_folder, so this copy the script.sh file that exists in the same directory as Dockerfile, to the root folder of the container (/). But you can change both parameters, like: COPY src/script.sh /usr/local/bin/ , this copy from the src folder to usr/local/bin – andre-lx Jan 31 '19 at 10:21
1

As pointed out by @michael_bitard, source is a bash built-in. Default shell in ubuntu is dash as can be seen here:

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

To use bash to run the command, change the RUN instruction to

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

Another option is to set the BASH_ENV environment variable, which should source the specified file (/home/ubuntu/.bashrc) before running the bash script catkin_make as mentioned here.

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"
Bless
  • 5,052
  • 2
  • 40
  • 44
  • wow! I assume as I didn't write the shell script, that it is for bash, so dash cant run it? Or is there a way to just use dash? (2) Also when you say "another option", all you mean is that I could add a -i to where your sample was running catkin make with just the -c right? – pitosalas Jan 31 '19 at 01:37
  • Trying your suggestion, what does this mean: Step 17/30 : RUN cd ~/catkin_ws/src && /bin/bash -c -i "catkin_init_workspace" ---> Running in e16b435a0439 bash: cannot set terminal process group (1): Inappropriate ioctl for device bash: no job control in this shell bash: /home/ubuntu/catkin_ws/devel/setup.bash: No such file or directory – pitosalas Jan 31 '19 at 01:57
  • @pitosalas Yes. If the script is created for bash, most likely it won't be compatible for dash if the script is using specific bash features. – Bless Jan 31 '19 at 05:10
  • I guess bash can't be run interactively (bash with `-i`) in Dockerfile instructions. I've removed it from the answer and added another alternate option. Hope this helps! – Bless Jan 31 '19 at 05:12
  • for some reason the script authors have ifs inside which check whether its being run interactively, and if not, skip important steps. Don't know why they do that, but, is there a way to get a script written by others to think it's being run interactively? – pitosalas Feb 01 '19 at 12:57
  • @pitosalas If you really need the script to be interactive, I guess you can pass `-i` flag and ignore the `Inappropriate ioctl for device` message, since the build itself is successful even with `-i` flag. If the scripts needs user input you might need something like [expect](http://www.manpagez.com/man/1/expect/). Regarding the error in the second comment you posted, I just looked at it more carefully and noticed `/home/ubuntu/catkin_ws/devel/setup.bash: No such file or directory`. It looks like this file is not copied to docker. Could you confirm this? – Bless Feb 01 '19 at 13:30