Search code examples
python-2.7shellcommandsubprocessexternal

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!


Solution

  • 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"])