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.
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.
Related
I'm running the next piece of code to check the type of my file:
import subprocess as sub
output = sub.check_output(["file", "test.py"]).decode('ascii')
#output=sub.check_output(["file","C:/Users/Roger.That/PycharmProjects/test/test.py"]).decode('ascii')
and I keep getting the following error:
Traceback (most recent call last):
File "C:/Users/Roger That/PycharmProjects/test/test.py", line 2, in <module>
output = sub.check_output(["file", "test.py"]).decode('ascii')
File "C:\Users\Roger That\AppData\Local\Programs\Python\Python37-32\lib\subprocess.py", line 395, in check_output
**kwargs).stdout
File "C:\Users\Roger That\AppData\Local\Programs\Python\Python37-32\lib\subprocess.py", line 472, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\Users\Roger That\AppData\Local\Programs\Python\Python37-32\lib\subprocess.py", line 775, in __init__
restore_signals, start_new_session)
File "C:\Users\Roger That\AppData\Local\Programs\Python\Python37-32\lib\subprocess.py", line 1178, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
The full path of my test.py : "C:/Users/Roger.That/PycharmProjects/test/test.py"
output from gitbash :
$ file /c/Users/Roger\ That/PycharmProjects/test/test.py
/c/Users/Roger That/PycharmProjects/test/test.py: ASCII text, with CRLF line terminators
Any chance that it is related to the fact that I have a dot between "Roger" and "That"? Although it doesn't work also when I use the relative path (only the file name)
Update
I changed my user's dir name from Roger that to Roger.that, but it still didn't help:
python /c/Users/Roger.That/PycharmProjects/test/test.py
same error..
checked also :
import subprocess as sub
output = sub.check_output(["ls" "-l"])
got same error
I created from scratch the virtual environment and it solved my problem.
I would like to execute an external compiled program in Python. In shell,
./bin/myProgram ./dir1/arg1 ./dir/arg2 arg3 arg3 arg4
And my Python script looks like:
import subprocess
subprocess.call(["./Users/Solar/Desktop/parent/child1/child2/bin/myProgram",
"/Users/Solar/Desktop/parent/child1/child2/dir1/arg1",
"/Users/Solar/Desktop/parent/child1/child2/dir1/arg2",
"arg3", "arg4", "arg5"])
But I get this error:
Traceback (most recent call last):
File "/Users/Solar/Desktop/test.py", line 5, in <module>
"32", "0.06", "15"])
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Process finished with exit code 1
Could you help me? Thank you in advance!!
It's solved, I just had to execute
subprocess.call(["/Users/Solar/Desktop/parent/child1/child2/bin/myProgram",
"/Users/Solar/Desktop/parent/child1/child2/dir1/arg1",
...
Instead of
subprocess.call(["./Users/Solar/Desktop/parent/child1/child2/bin/myProgram",
"/Users/Solar/Desktop/parent/child1/child2/dir1/arg1",
...
Thank you people!!
when subprocess.Popen issues
OSError: [Errno 2] No such file or directory
that's only because the executable cannot be found (if one of the file-arguments was not found it's the sub-process which reports the error, and no exception is thrown)
In your case ./Users/... is not likely to be valid considering that /Users/ is valid (root against current dir) so that's your problem.
"./Users/Solar/Desktop/parent/child1/child2/bin/myProgram" should be "/Users/Solar/Desktop/parent/child1/child2/bin/myProgram"
Note: better coding could have avoided the error:
import subprocess
root = "/Users/Solar/Desktop/parent/child1/child2"
subprocess.call([os.path.join(root,"bin/myProgram"),
os.path.join(root,"dir1/arg1"),
os.path.join(root,"dir1/arg2"),
"arg3", "arg4", "arg5"])
from subprocess import call
import os
call(['robot '+os.getcwd()+'\\aaa.robot'])
file_dir: D:/aaa/test/aaa.robot
script for now in same dir
Output:
Traceback (most recent call last):
File "__init.py", line 7, in <module>
call(['robot '+os.getcwd()+'\\aaa.robot'])
File "C:\Python27\lib\subprocess.py", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "C:\Python27\lib\subprocess.py", line 710, in __init_
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 958, in _execut
startupinfo)
WindowsError: [Error 2] Nie mo┐na odnalečŠ okreťlonego pliku
I just cant handle it. I dont get why in python tunning anything is so complicated :(
I want same result as this line (written directly to cmd):
/>robot aaa.robot
Here is another way
import robot
logFile = open('mylog.txt', 'w')
robot.run("tmp.robot",stdout=logFile)
subprocess expects a list but you're inputting a string ('robot '+os.getcwd()+'\\aaa.robot').
Try:
call(['C:/Python27/python.exe', '-m', 'robot', 'D:/aaa/test/aaa.robot'])
or
call(['C:/Python27/Scripts/robot.bat', 'D:/aaa/test/aaa.robot'])
I am using windows and struggeling to get this work...
I can execute this in cmd.exe:
"C:\Program Files (x86)\Test 123\Test.exe" "H:\Test Test\file.txt" -f "doStuff"
but when I try to do it in python:
subprocess.call([r'"C:\Program Files (x86)\Test 123\Test.exe" "H:\Test Test\file.txt" -f "doStuff"'])
I get this error:
Traceback (most recent call last):
File "testing12.py", line 20, in <module>
subprocess.call([r'"C:\Program Files (x86)\Test 123\Test\Test.exe" "H:\Test Test\Folder\file.txt" -f "doStuff"'])
File "c:\Python27\lib\subprocess.py", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "c:\Python27\lib\subprocess.py", line 709, in __init__
errread, errwrite)
File "c:\Python27\lib\subprocess.py", line 957, in _execute_child
startupinfo)
WindowsError: [Error 5] Access is denied
How can I execute it properly? Thanks.
If you're going to pass in an array, make it an actual array -- one argument per parameter, separated by commas. Otherwise you'll need to use shell=True, which has all the (generally undesirable) side effects of invoking a shell (and should just pass in your command string as a string, no array called for in that use case).
subprocess.call([
"C:\Program Files (x86)\Test 123\Test.exe",
"H:\Test Test\file.txt",
"-f", "doStuff"])
If you don't use commas between your strings, they're consolidated together.
Why if I run subprocess.check_output('ls') everything is working but when I add argument to command like: subprocess.check_output('ls -la') I get error:
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/subprocess.py", line 537, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1259, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
How can I pass command arguments into subprocess.check_output()?
You need to split the arguments into a list:
subprocess.check_output(['ls', '-la'])
The subprocess callables do not parse the command out to individual arguments like the shell does. You either need to do this yourself or you need to tell subprocess to use the shell explicitly:
subprocess.check_output('ls -la', shell=True)
The latter is not recommended as it can expose your application to security vulnerabilities. You can use shlex.split() to parse a shell-like command line if needed:
>>> import shlex
>>> shlex.split('ls -la')
['ls', '-la']
You might find sh.py more friendly:
import sh
print sh.ls("-la")