4

I want to run a set of docker commands from python. I tried creating a script like below and run the script from python using paramiko ssh_client to connect to the machine where the docker is running:

#!/bin/bash

   # Get container ID
   container_id="$(docker ps | grep hello | awk '{print $1}')"

   docker exec -it $container_id sh -c "cd /var/opt/bin/ && echo $1 && 
   echo $PWD && ./test.sh -q $1"

But docker exec ... never gets executed.

So I tried to run the below python script below, directly in the machine where the docker is running: import subprocess

docker_run = "docker exec 7f34a9c1b78f /bin/bash -c \"cd 
/var/opt/bin/ && ls -a\"".split()
subprocess.call(docker_run, shell=True)

I get a message: "Usage: docker COMMAND..."

But I get the expected results if I run the command

docker exec 7f34a9c1b78f /bin/bash -c "cd /var/opt/bin/ && ls -a" directly in the machine

How to run multiple docker commands from the python script? Thanks!

4
  • This container_id="$(docker ps | grep <container> | awk '{print $1}')" doesn't look right. I think you forgot to replace <container> with the actual container. Commented Sep 10, 2018 at 17:00
  • When I ran the actual script I added the actual container. Let me modify the question so it is clear. Commented Sep 10, 2018 at 17:03
  • Use docker-py instead of hardcoding all of this subprocess work. I use it very frequently and have been happy with it Commented Sep 10, 2018 at 17:05
  • I am trying to avoid docker module, as I don't want to install anything new on the system. Also, I am not sure if the container is exposed. Commented Sep 10, 2018 at 17:10

2 Answers 2

4

You have a mistake in your call to subprocess.call. subprocess.call expects a command with a series of parameters. You've given it a list of parameter pieces.

This code:

docker_run = "docker exec 7f34a9c1b78f /bin/bash -c \"cd 
/var/opt/bin/ && ls -a\"".split()
subprocess.call(docker_run, shell=True)

Runs this:

subprocess.call([
   'docker', 'exec', '7f34a9c1b78f', '/bin/bash', '-c', 
   '"cd', '/var/opt/bin/', '&&', 'ls', '-a"'
 ], shell=True)

Instead, I believe you want:

subprocess.call([
   'docker', 'exec', '7f34a9c1b78f', '/bin/bash', '-c', 
   '"cd /var/opt/bin/ && ls -a"' # Notice how this is only one argument.
 ], shell=True)

You might need to tweak that second call. I suspect you don't need the quotes ('cd /var/opt/bin/ && ls -a' might work instead of '"cd /var/opt/bin/ && ls -a"'), but I haven't tested it.

Sign up to request clarification or add additional context in comments.

1 Comment

Tried below 3 ways, still get the "docker usage" message subprocess.call(['docker', 'exec', '7f34a9c1b78f', '/bin/bash', '-c', 'cd /opt/bin/ && ls -a'], shell=True) subprocess.call(['docker', 'exec', '7f34a9c1b78f', '/bin/bash', '-c', '"cd /opt/bin/ && ls -a"'], shell=True) subprocess.call(['docker', 'exec', '7f34a9c1b78f', '/bin/bash', '-c', '\"cd /opt/bin/ && ls -a\"'], shell=True)
3

Following are a few methods worked: Remove double quotes:

subprocess.call([
    'docker', 'exec', '7f34a9c1b78f', '/bin/bash', '-c', 
    'cd /opt/teradata/tdqgm/bin/ && ./support-archive.sh -q 6b171e7a-7071-4975-a3ac-000000000241'
    ])

If you are not sure of how the command should be split up to pass it as an argument of subprocess method, shlex module: https://docs.python.org/2.7/library/shlex.html#shlex.split

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.