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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.