0

I have a Python script I wrote to be called from the command line. I am writing a GUI wrapper but do not want to change the main function. In the GUI code, I am calling the script using subprocess.run(['./executable.py', input]) but the input is not visible in executable.py's sys.argv list. How do I pass the input such that it would be visible to sys.argv?

Here is a test script I have saved as test.py (made it executable chmod +x test.py):

#!/usr/bin/env python
# script to test using sys.argv with subprocess

import sys

print(sys.argv)

Here is what I get when calling this from the command line:

$> ./test.py input.txt
['./test.py', 'input.txt']

Here is what I get when calling this from within a python shell:

>>> import subprocess
>>> output = subprocess.run(['./test.py', 'input.txt'], shell=True, stdout=subprocess.PIPE)
>>> >>> print(output.stdout)
b"['./test.py']\n"

How do I get input.txt to show up in sys.argv?

Steven C. Howell
  • 16,902
  • 15
  • 72
  • 97

1 Answers1

0

The safest way to do this is to simply remove shell=True:

>>> import subprocess
>>> output = subprocess.run(['./test.py', 'input.txt'], stdout=subprocess.PIPE)
>>> print(output.stdout)
b"['./test.py', 'input.txt']\n"

The other option is to combine the list of inputs into a single string:

>>> import subprocess
>>> output = subprocess.run('./test.py input.txt', shell=True, stdout=subprocess.PIPE)
>>> print(output.stdout)
b"['./test.py', 'input.txt']\n"

I am not completely sure why the original method (with a list of inputs and shell=True fails) fails. Regardless, to avoid running unintended commands/code it is best to avoid using shell=True (note on when you should use shell=True).

Steven C. Howell
  • 16,902
  • 15
  • 72
  • 97
  • It's better to remove the `shell=True` instead. – jordanm May 29 '17 at 20:40
  • @StevenC.Howell `shell=True` is quite risky, for details have a look at the documentation: https://docs.python.org/3/library/subprocess.html#security-considerations – olisch May 29 '17 at 20:59