pythonsubprocess

How do I use subprocess.check_output()?


I want to run the following command from within a Python program: python py2.py -i test.txt

I tried using subprocess.check_output as follows:

py2output = subprocess.check_output(['python py2.py', '-i', 'test.txt'])
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])

Solution

  • The right answer (using Python 2.7 and later, since check_output() was introduced then) is:

    py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])
    

    To demonstrate, here are my two programs:

    py2.py:

    import sys
    print sys.argv
    

    py3.py:

    import subprocess
    py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
    print('py2 said:', py2output)
    

    Running it:

    $ python3 py3.py
    py2 said: b"['py2.py', '-i', 'test.txt']\n"
    

    Here's what's wrong with each of your versions:

    py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
    

    First, str('python py2.py') is exactly the same thing as 'python py2.py'—you're taking a str, and calling str to convert it to an str. This makes the code harder to read, longer, and even slower, without adding any benefit.

    More seriously, python py2.py can't be a single argument, unless you're actually trying to run a program named, say, /usr/bin/python\ py2.py. Which you're not; you're trying to run, say, /usr/bin/python with first argument py2.py. So, you need to make them separate elements in the list.

    Your second version fixes that, but you're missing the ' before test.txt'. This should give you a SyntaxError, probably saying EOL while scanning string literal.

    Meanwhile, I'm not sure how you found documentation but couldn't find any examples with arguments. The very first example is:

    >>> subprocess.check_output(["echo", "Hello World!"])
    b'Hello World!\n'
    

    That calls the "echo" command with an additional argument, "Hello World!".

    Also:

    -i is a positional argument for argparse, test.txt is what the -i is

    I'm pretty sure -i is not a positional argument, but an optional argument. Otherwise, the second half of the sentence makes no sense.