Bash, Docker: Run a Script in Container and Redirect Output to a File on the Host Machine

Posted August 9, 2020 by Yaroslav Grebnov ‐ 2 min read

We have a Docker container, which we construct dynamically. We need to copy a Bash script from the host machine to the container and then to execute this script in the container, but from the host machine. The purpose of doing like this is that we need the output of the script execution on the host machine.

We will create a Docker container using docker-compose. We will use a simple docker-compose file, constructing a container named testContainer based on the lentos:latest image. Create a docker-compose.yml file with the following code:

version: '3.5'
services:
  testContainer:
    image: centos:latest
    container_name: testContainer
    tty: true

Please note the line containing tty:true. The purpose of this line is to prevent the container from exiting right after creation. More details on this: Docker: Prevent container from exiting immediately after creation

The next step is to create a script which we will execute in the container. Create a file scriptInContainer.sh with the following code:

#!/bin/bash

echo "Output from the testContainer"

Make scriptInContainer.sh executable:

chmod +x scriptInContainer.sh

And now, we will create our main script, testScript.sh.

Start from creating a testContainer using docker-compose:

docker-compose up -d

Next, use docker cp command to copy the scriptInContainer.sh to the /tmp directory inside the testContainer:

docker cp ./scriptInContainer.sh testContainer:/tmp/scriptInContainer.sh

Using docker exec command, execute scriptInContainer.sh and redirect output to a script.out file:

docker exec testContainer bash -c ". /tmp/scriptInContainer.sh" > script.out

Destroy testContainer using docker-compose down command:

docker-compose down

Check if the scriptInContainer.sh has been executed correctly. We will implement this check by verifying if the script.out file contains a string “testContainer”. If it does, we print out a successful check result message (a failed check result message otherwise):

if [ $( cat ./script.out | grep "testContainer" | wc -l ) -eq 1 ]; then
  echo "The output file contains the expected output"
else
  echo "The output file does not contain the expected output"
fi

Make testScript.sh executable and run it:

chmod +x testScript.sh
./testScript.sh

Output:

The output file contains the expected output

The testScript.sh file complete listing:

#!/bin/bash

docker-compose up -d
sleep 10

docker cp ./scriptInContainer.sh testContainer:/tmp/scriptInContainer.sh

docker exec testContainer bash -c ". /tmp/scriptInContainer.sh" > script.out

docker-compose down

if [ $( cat ./script.out | grep "testContainer" | wc -l ) -eq 1 ]; then
  echo "The output file contains the expected output"
else
  echo "The output file does not contain the expected output"
fi