Dreams
Dreams

Reputation: 6122

Running subprocess.call from python script

I have a functionality where I need to run a command inside a python script. From another answer, I figured call from subprocess module is the safest way. But, I am unable to work through it. I am using python 2.7

This is a smaller version of what I am trying :

import subprocess
a = "echo hello"
subprocess.call([a])

It gives me the following error :

 subprocess.call([a])
  File "/usr/lib/python2.7/subprocess.py", line 522, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

I am unable to figure out why!

Upvotes: 0

Views: 507

Answers (2)

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

You can pass the commands as a string or a list but not as a string in a list, otherwise the system is trying to run the echo hello process (which doesn't exist, obviously, which explains the OSError: [Errno 2] No such file or directory error message). Passing it as a string requires shell=True on some systems.

And shell=True is also required with shell built-ins like the echo command (which has a non built-in version in /bin on some systems, just to add to the confusion)

import subprocess
subprocess.call(["echo","hello"],shell=True)

For non built-in commands (I assume that echo is just a test here), avoid shell=True, since it adds an unnecessary shell layer which degrades startup performance, and is prone to code injection (echo hello; rm -rf everything_on_disk)

To run your favorite editor for instance, you can do:

subprocess.call(["emacs","readme.txt"])

Upvotes: 1

user3778137
user3778137

Reputation:

The code you have written has issues, subprocess.call takes in a list where the first element of the list is the command. In your case it is echo and hello is your argument it should be the next value in the list. So your code should look like this.

import subprocess

a = [ "echo","hello"]
subprocess.call(a)

Upvotes: 1

Related Questions