"/bin/sh: 1: MY_COMMAND: not found"
Taken from /bin/sh: 1: gvm: not found, which would say more or less:
Your shell is /bin/sh, but source expects /bin/bash, perhaps because it puts its initialization in
~/.bashrc
.
In other words, this problem can occur in any setting where the "sh" shell is used instead of the "bash", causing "/bin/sh: 1: MY_COMMAND: not found"
.
In the Dockerfile case, use the recommended
RUN /bin/bash -c 'source /opt/ros/melodic/setup.bash'
or with the "[]
" (which I would rather not use):
RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash"]
Every new RUN of a bash is isolated, "starting at 0". For example, mind that setting WORKDIR /MY_PROJECT
before the bash commands in the Dockerfile does not affect the bash commands since the starting folder would have to be set in the ".bashrc" again. It needs cd /MY_PROJECT
even if you have set WORKDIR.
Side-note: do not forget the first "/" before "opt/../...". Else, it will throw the error:
/bin/bash: opt/ros/melodic/setup.bash: No such file or directory
Works:
=> [stage-2 18/21] RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash"] 0.5s
=> [stage-2 19/21] [...]
You might also put the commands you want to execute in a single bash script and run that bash script in the Dockerfile (though I would rather put the bash commands in the Dockerfile as well, just my opinion):
#!/bin/bash
set -e
source /opt/ros/melodic/setup.bash
PS: You can also put many bash commands in a row:
RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash && MY_BASH_COMMAND && MY_BASH_COMMAND"]
or same with
RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash;MY_BASH_COMMAND;MY_BASH_COMMAND"]
or in many lines with
RUN /bin/bash -c 'source /opt/ros/melodic/setup.bash &&\
cd /MY_PROJECT &&\
catkin_make -j8;\
echo "source /MY_PROJECT/devel/setup.bash" >> ~/.bashrc'
or same with
RUN /bin/bash -c 'source /opt/ros/melodic/setup.bash;\
cd /MY_PROJECT;\
catkin_make -j8;\
echo "source /MY_PROJECT/devel/setup.bash" >> ~/.bashrc'
Mind that when using RUN ["/bin/bash", "-c", "..."]
with this []
frame, this works only in a one-liner. At least I could not (!) get it to run with:
RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash && \
cd /MY_PROJECT && \
catkin_make -j8"]
nor with
RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash &&
cd /MY_PROJECT &&
catkin_make -j8"]
nor with
RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash; \
cd /MY_PROJECT; \
catkin_make -j8"]
nor with
RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash;
cd /MY_PROJECT;
catkin_make -j8"]
The error was always like:
executor failed running ... exit code: 127
PS2: You can also add the source command to the .bashrc
(the "run commands" at the start of the bash) so that this is loaded at every start of the bash:
RUN ["/bin/bash", "-c", "echo 'source /MY_PROJECT/devel/setup.bash' >> ~/.bashrc"]
or
RUN /bin/bash -c 'echo "source /MY_PROJECT/devel/setup.bash" >> ~/.bashrc'
Related videos on Youtube
questionto42standswithUkraine
Updated on September 18, 2022Comments
-
questionto42standswithUkraine over 1 year
Error
During
docker build -t MY_IMAGE_NAME .
, using a Dockerfile for a ROS project, at lineRUN source /opt/ros/melodic/setup.bash
the following error appeared:
=> 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
Test
To test this, I created an image of a step before the error step, and checked the command inside the container: and it worked. Thus, the "source" command is available in the bash of the container. How can it be not available in the image, then?
docker run -dit --name MY_CONTAINER_NAME -v /opt/ros/melodic/ MY_IMAGE:latest docker exec -it MY_CONTAINER_NAME /bin/bash
Fyi:
-v /opt/ros/melodic/
mounts the volume-v
, else/opt/ros/melodic/
would be empty. By default, only the "build context", in this case where you start the Dockerfile, is not empty.Now in the container, in the bash (which was loaded using
/bin/bash
above):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
And I could have just checked it directly anyway, works:
root@1b2bdc5131sy:/# source /opt/ros/melodic/setup.bash
Question
Since the "source" command works in the container MY_CONTAINER_NAME, how can I get the
bash
shell working in the underlying image MY_IMAGE_NAME during thedocker build
of the Dockerfile, instead of using thesh
shell?-
stark about 3 yearssource is a bash built-in, not a command.
-
questionto42standswithUkraine about 3 years@stark It is just the example here. You would have the same problem with any other real command that is not built-in. If it is built-in or not does not change the idea here, and I wonder how I should name it then.
-