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")
Related
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 trying to count the number of lines in a file using Python functions. Within the current directory, while os.system("ls") finds the file, the command subprocess.Popen(["wc -l filename"], stdout=subprocess.PIPE) does not work.
Here is my code:
>>> import os
>>> import subprocess
>>> os.system("ls")
sorted_list.dat
0
>>> p = subprocess.Popen(["wc -l sorted_list.dat"], stdout=subprocess.PIPE)File "<stdin>", line 1, in <module>
File "/Users/a200/anaconda/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/Users/a200/anaconda/lib/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
You should pass the arguments as a list (recommended):
subprocess.Popen(["wc", "-l", "sorted_list.dat"], stdout=subprocess.PIPE)
Otherwise, you need to pass shell=True if you want to use the whole "wc -l sorted_list.dat" string as a command (not recommended, can be a security hazard).
subprocess.Popen("wc -l sorted_list.dat", shell=True, stdout=subprocess.PIPE)
Read more about shell=True security issues here.
The error occurs because you are trying to run a command named wc -l sorted_list.dat, that is, it is trying to find a file named like "/usr/bin/wc -l sorted dat".
Split your arguments:
["wc", "-l", "sorted_list.dat"]
I try to call a shellscript via the subprocess module in Python 2.6.
import subprocess
shellFile = open("linksNetCdf.txt", "r")
for row in shellFile:
subprocess.call([str(row)])
My filenames have a length ranging between 400 and 430 characters.
When calling the script I get the error:
File "/usr/lib64/python2.6/subprocess.py", line 444, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.6/subprocess.py", line 595, in __init__
errread, errwrite)
File "/usr/lib64/python2.6/subprocess.py", line 1106, in _execute_child
raise child_exception
OSError: [Errno 36] File name too long
An example of the lines within linksNetCdf.txt is
./ShellScript 'Title' 'Sometehing else' 'InfoInfo' 'MoreInformation' inputfiile outputfile.txt 3 2
Any ideas how to still run the script?
subprocess.call can take the command to run in two ways - either a single string like you'd type into a shell, or a list of the executable name followed by the arguments.
You want the first, but were using the second
import subprocess
shellFile = open("linksNetCdf.txt", "r")
for row in shellFile:
subprocess.call(row, shell=True)
By converting your row into a list containing a single string, you're saying something like "Run the command named echo these were supposed to be arguments with no arguments"
You need to tell subprocess to execute the line as full command including arguments, not just one program.
This is done by passing shell=True to call
import subprocess
cmd = "ls " + "/tmp/ " * 30
subprocess.call(cmd, shell=True)
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.
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.