javex
javex

Reputation: 7544

NamedTemporaryFile cannot be acessed from command line

I have the following (simplified) code:

with NamedTemporaryFile() as f:
    f.write(zip_data)
    f.flush()
    subprocess.call("/usr/bin/7z x %s" % f.name)

It dies with the following error:

Traceback (most recent call last):
  File "decrypt_resource.py", line 70, in <module>
    unpack(sys.argv[2])
  File "decrypt_resource.py", line 28, in unpack
    print(subprocess.check_output(cmd))
  File "/usr/lib/python2.7/subprocess.py", line 568, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

However, if I use NamedTemporaryFile(delete=False) and then print & execute the command, it works. What's wrong here?

My System is an ArchLinux with a 3.9.5-1-ARCH kernel.

Upvotes: 2

Views: 676

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122092

You are using subprocess.call() incorrectly.

Pass in a list of arguments:

subprocess.call(["/usr/bin/7z", "x", f.name])

The argument is not handled by a shell and is not parsed out like a shell would do. This is a good thing as it prevents a security problem with untrusted command line arguments.

Your other options include using shlex.split() to do the whitespace splitting for you, or, as a last resort, telling subprocess to use a shell for your command with the shell=True flag. See the big warning on the subprocess documentation about enabling the shell.

Upvotes: 3

Related Questions