basicbop
basicbop

Reputation: 3

Execute local shell script using docker run interactive

Can I execute a local shell script within a docker container using docker run -it ?

Here is what I can do:

$ docker run -it 5ee0b7440be5                                                                                                                                                                                                                           
bash-4.2# echo "Hello"
Hello
bash-4.2# exit
exit

I have a shell script on my local machine

hello.sh:

echo "Hello"

I would like to execute the local shell script within the container and read the value returned:

$ docker run -it 5e3337440be5 #Some way of passing a reference to hello.sh to the container.
Hello                                                                                                                                                                                                                     

Upvotes: 0

Views: 3121

Answers (2)

cam
cam

Reputation: 5198

You can use a bind-mount to mount a local file to the container and execute it. When you do that, however, be aware that you'll need to be providing the container process with write/execute access to the folder or specific script you want to run. Depending on your objective, using Docker for this purpose may not be the best idea. See @David Maze's answer for reasons why. However, here's how you can do it:

Assuming you're on a Unix based system and the hello.sh script is in your current directory, you can mount that single script to the container with -v $(pwd)/hello.sh:/home/hello.sh.

This command will mount the file to your container, start your shell in the folder where you mounted it, and run a shell:

docker run -it -v $(pwd)/hello.sh:/home/hello.sh --workdir /home ubuntu:20.04 /bin/sh

root@987eb876b:/home ./hello.sh
Hello World!

This command will run that script directly and save the output into the variable output:

output=$(docker run -it -v $(pwd)/hello.sh:/home/test.sh ubuntu:20.04 /home/hello.sh)

echo $output
Hello World!

References for more information:

Upvotes: 1

David Maze
David Maze

Reputation: 158947

A specific design goal of Docker is that you can't. A container can't access the host filesystem at all, except to the extent that an administrator explicitly mounts parts of the filesystem into the container. (See @tentative's answer for a way to do this for your use case.)

In most cases this means you need to COPY all of the scripts and support tools into your image. You can create a container running any command you want, and one typical approach is to set the image's CMD to do "the normal thing the container will normally do" (like run a Web server) but to allow running the container with a different command (an admin task, a background worker, ...).

# Dockerfile
FROM alpine
...
COPY hello.sh /usr/local/bin
...
EXPOSE 80
CMD httpd -f -h /var/www
docker build -t my/image .
docker run -d -p 8000:80 --name web my/image
docker run --rm --name hello my/image \
  hello.sh

In normal operation you should not need docker exec, though it's really useful for debugging. If you are in a situation where you're really stuck, you need more diagnostic tools to be understand how to reproduce a situation, and you don't have a choice but to look inside the running container, you can also docker cp the script or tool into the container before you docker exec there. If you do this, remember that the image also needs to contain any dependencies for the tool (interpreters like Python or GNU Bash, C shared libraries), and that any docker cpd files will be lost when the container exits.

Upvotes: 1

Related Questions