subprocess.Popen: how to pass commands with single and double quotes

84 Views Asked by At

I need to run a bash shell command (Debian) through Python and collect the output.

The command is

curl -H "Content-type:application/json" https://api.example.com/api/v1/login -d '{ "ldap": true, "username": "myusername", "ldapPass": "mypassword", "ldapOptions": {} }'

With the right URL, userid, and password substituted in, this command works in the bash shell. I would like to run this command in a Python program using subprocess.Popen(cmd...)

Obviously I have to assign something to cmd before calling Popen(cmd), but I can't figure out what. I tried adding escape characters like this:

cmd = "curl -H \"Content-type:application/json\" https://api.example.com/api/v1/login -d '{ \"ldap\": true, \"username\": \"myusername\", \"ldapPass\": \"mypassword\", \"ldapOptions\": {} }'"
p = subprocess.Popen(cmd.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
(child_stderr, child_stdout) = p.communicate()

It didn't work, and threw an exeption.

I then tried building the cmd array by hand, and then not splitting it during the Popen call:


cmd = ["curl","-H","\"Content-type:application/json\"", "https://api.example.com/api/v1/login", "-d","'{ \"ldap\": true, \"username\": \"myusername\", \"ldapPass\": \"mypassword\", \"ldapOptions\": {} }'"]

print(cmd)
print(" ".join(cmd))

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
(child_stderr, child_stdout) = p.communicate()

This didn't work either and threw an exception.

Interestingly, when I copied the output of " ".join(cmd), and ran it in the shell, it worked fine.

I have used other cases like

cmd = ["ps", "-ef"]

and it worked fine.

How can I assign the proper value to cmd (with its single and double quotes) so that it will run properly using Python's subprocess.Popen()?

0

There are 0 best solutions below