"/bin/sh: 1: MY_COMMAND: not found"

16,380

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'
Share:
16,380

Related videos on Youtube

questionto42standswithUkraine
Author by

questionto42standswithUkraine

Updated on September 18, 2022

Comments

  • questionto42standswithUkraine
    questionto42standswithUkraine over 1 year

    Error

    During docker build -t MY_IMAGE_NAME ., using a Dockerfile for a ROS project, at line

    RUN 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 the docker build of the Dockerfile, instead of using the sh shell?

    • stark
      stark about 3 years
      source is a bash built-in, not a command.
    • questionto42standswithUkraine
      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.