Python - unable to call system command - python

I have some python code, from which I want to call another program. This program will
Print some output to STDOUT
Write a file to disk
Using call I get the following behavior;
from subprocess import call
call(['./tango_x86_64_release', 'VTS1 ct="N" nt="N" ph="7.2" te="303" io="0.02" seq="MKHPYEEFPTGSKSPYNMSRGAHPGAV"'])
34, File not properly written, try writing it up again,
1
This happens regardless if if the arguments are split into a list or not;
call(['./tango_x86_64_release', 'VTS1', 'ct="N"', 'nt="N"', 'ph="7.2"', 'te="303"', 'io="0.02"', 'seq="MKHPYEEFPTGSKSPYNMSRGAHPGAV"'])
34, File not properly written, try writing it up again,
1
I can call this same command from the my terminal
./tango_x86_64_release VTS1 ct="N" nt="N" ph="7.2" te="303" io="0.02" seq="MKHPYEEFPTGSKSPYNMSRGAHPGAV"
Which works and gives an exit status of 0.
It seems like its the writing to disk which is causing issues, if I break the command then I get the appropriate warning message (i.e. remove an argument, it warns me that the argument is missing).
Using subprocess.Popen() gives an OSError;
import subprocess as sub
output = sub.Popen('./tango_x86_64_release VTS1 ct="N" nt="N" ph="7.2" te="303" io="0.02" seq="MKHPYEEFPTGSKSPYNMSRGAHPGAV"', stdout=sub.PIPE, stderr=sub.PIPE)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Any help greatly appreciated

Use shlex.split to split the command for you:
import shlex
call(shlex.split('./tango_x86_64_release VTS1 ct="N" nt="N" ph="7.2" te="303" io="0.02" seq="MKHPYEEFPTGSKSPYNMSRGAHPGAV"'))
Note that although you might be able to solve your problem by adding shell=True, you should avoid it if possible, since it can be a security risk (search for "shell injection").

Try to add shell=True to the Popen call.
Also see:
Why does subprocess.Popen() with shell=True work differently on Linux vs Windows?
Popen error: [Errno 2] No such file or directory
Documentation (and why Passing shell=True can be a security hazard)

Related

Python subprocess permissionerror

When I try to execute a file which is located inside the Program Files directory, I get a PermissionError execption.
excat error
Traceback (most recent call last):
File "Build.py", line 24, in <module>
subprocess.Popen([buildCMD], stdin=subprocess.PIPE)
File "subprocess.py", line 854, in __init__
File "subprocess.py", line 1307, in _execute_child
PermissionError: [WinError 5] Zugriff verweigert
[23948] Failed to execute script 'Build' due to unhandled exception!
Code:
import subprocess
buildCMD = '"C:/Program Files/Microchip/xc8/v2.32/bin/xc8-cc.exe" -mcpu=16f1787 -Wl,-Map=.build/main.build.map -DXPRJ_default=default -Wl,--defsym=__MPLAB_BUILD=1 -mdfp=C:/Program Files/Microchip/MPLABX/v5.50/packs/Microchip/PIC12-16F1xxx_DFP/1.2.63/xc8 -fno-short-double -fno-short-float -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -msummary=-psect,-class,+mem,-hex,-file -ginhx32 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -Wl,--memorysummary,.build/memoryfile.xml -o .build/main.build.hex main.c'
subprocess.Popen([buildCMD], stdin=subprocess.PIPE)
Passing a string as a list is doubly wrong, though Windows is somewhat more forgiving than real computers here. You want either
subprocess.run([
"C:/Program Files/Microchip/xc8/v2.32/bin/xc8-cc.exe",
"-mcpu=16f1787", "-Wl,-Map=.build/main.build.map",
"-DXPRJ_default=default", "-Wl,--defsym=__MPLAB_BUILD=1",
"-mdfp=C:/Program Files/Microchip/MPLABX/v5.50/packs/Microchip/PIC12-16F1xxx_DFP/1.2.63/xc8",
"-fno-short-double", "-fno-short-float", "-fasmfile",
"-maddrqual=ignore", "-xassembler-with-cpp", "-mwarn=-3",
"-Wa,-a", "-msummary=-psect,-class,+mem,-hex,-file",
"-ginhx32", "-Wl,--data-init", "-mno-keep-startup",
"-mno-osccal", "-mno-resetbits", "-mno-save-resetbits",
"-mno-download", "-mno-stackcall", "-std=c99", "-gdwarf-3",
"-mstack=compiled:auto:auto",
"-Wl,--memorysummary,.build/memoryfile.xml",
"-o", ".build/main.build.hex", "main.c"],
stdin=subprocess.PIPE,
check=True)
or the same as a string (but then with correct quoting around the arguments with spaces in them, notably -mdfp=C:/Program Files/...) and with shell=True (which however you usually want to avoid.)
Notice also the addition of check=True to have Python raise an exception if the subprocess fails, and the preference for subprocess.run() over subprocess.Popen unless you specifically require the subprocess to run alongside with your Python script, and then commit to managing the process object until it is terminated.

Why subprocess.call () is showing error in linux?

Let us consider Linux platform where I need to execute a program called smart.exe which uses input.dat file. Both the files are placed in the same directory with each file having the same file permission 777.
Now if I run the following command in the terminal window smart.exe is fully executed without any error.
$./smart.exe input.dat
On the other hand, if I use the following python script called my_script.py placed in the same directory, then I get an error.
my_script.py has the following code:
#!/usr/bin/python
import os, subprocess
exit_code = subprocess.call("./smart.exe input.dat", shell = False)
The error is as follows:
File "my_script.py", line 4, in <module>
exit_code = subprocess.call("./smart.exe input.dat", shell = False)
File "/usr/lib64/python2.6/subprocess.py", line 478, in call
p = Popen(*popenargs, **kwargs)
File "/usr/lib64/python2.6/subprocess.py", line 642, in __init__
errread, errwrite)
File "/usr/lib64/python2.6/subprocess.py", line 1234, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Can someone please tell me why this is happening. Please note that the smart.exe should take around 10 sec to fully complete. This may be a clue for the problem.
Please also advise if there is any other way to run smart.exe from my_script.py. Your solution is much appreciated!
You should decide if you want shell support or not.
If you want the shell to be used (which is not necessary here), you should use exit_code = subprocess.call("./smart.exe input.dat", shell=True). Then the shell interprets your command line.
If you don't want it (as you don't need it and want to avoid unnecessary complexity), you should do exit_code = subprocess.call(["./smart.exe", "input.dat"], shell=False).
(And there is no point naming your binarys .exe under Linux.)

subprocess.call() fails on Mac and Linux

I'm running into a weird issue with subprocess.call() function. I am trying to execute Java's 'jar' command using subprocess.call(). Here's the code:
import os
import subprocess
def read_war():
war_file_path = "jackrabbit-webapp-2.6.5.war"
java_home = os.environ['JAVA_HOME']
jar_path = os.path.join(java_home, 'bin', 'jar')
jar_cmd = jar_path + ' tvf ' + war_file_path
print "command to be executed is : " + jar_cmd
subprocess.call(jar_cmd)
read_war()
I'm using Python v2.7.3 on both Windows and Linux (Oracle Enterprise Linux).
On Windows 7, I see the contents of the war file being displayed. On Linux, however, I see a 'no such file or directory' error.:
$ python example.py
command to be executed is : /usr/local/tools/jdk1.7.0_15/bin/jar tvf jackrabbit-webapp-2.6.5.war
Traceback (most recent call last):
File "example.py", line 24, in <module>
read_war()
File "example.py", line 23, in read_war
subprocess.call(jar_cmd)
File "/usr/local/tools/Python-2.7.3/Lib/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/local/tools/Python-2.7.3/Lib/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/local/tools/Python-2.7.3/Lib/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
$
I've tried the command '/usr/local/tools/jdk1.7.0_15/bin/jar tvf jackrabbit-webapp-2.6.5.war' from command prompt and it works fine. So, nothing's wrong with the command.
I've tried various combinations of subprocess.call() - passing a string, passing a list etc. None of them worked. Any help at all would be appreciated.
Add shell=True to the call. On windows, the CreateProcess command does string parsing to separate the command and its various arguments. On linux, you only get string processing if you specifically tell subprocess to call the shell. Otherwise, it treats that entire string you handed in as the command and you don't get very far.
subprocess.call(jar_cmd, shell=True)
Use a list (sequence) argument instead of a string as the docs say:
args is required for all calls and should be a string, or a sequence
of program arguments. Providing a sequence of arguments is generally
preferred, as it allows the module to take care of any required
escaping and quoting of arguments (e.g. to permit spaces in file
names). If passing a single string, either shell must be True (see
below) or else the string must simply name the program to be executed
without specifying any arguments.
Example:
import os
import subprocess
def read_war():
war_file_path = "jackrabbit-webapp-2.6.5.war"
jar_path = os.path.join(os.environ['JAVA_HOME'], 'bin', 'jar')
jar_cmd = [jar_path, 'tvf', war_file_path]
print("command to be executed is: %s" % jar_cmd)
subprocess.check_call(jar_cmd)
read_war()
I've used check_call to raise an exception if the command returns non-zero exit status.

How do I run a command with string formatting?

I am using the subprocess module to run a command in python. But the problem is that I also want to include a string (for a file name) in the command.
An example of what I want to do:
from subprocess import call
command = "cd/DirectoryName"
call = [(command)]
In this specific example I want DirectoryName to be a variable determined by the user.
What I have tried to no avail:
Desktop=raw_input()
cmd="'cd %s'(Desktop/)"
call([cmd])
Here's the error I get when I try to run these commands in the python shell.
Chicken='Chicken'
command = 'say %s' % (Chicken)
print command
say Chicken
call([command])
Traceback (most recent call last):
File "/Applications/WingIDE.app/Contents/MacOS/src/debug/tserver/_sandbox.py", line 1, in <module>
# Used internally for debug sandbox under external interpreter
File "/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Just tried this and it made the shell crash.
Chicken="Chicken"
print Chicken
Chicken
call[("say %s" % (Chicken)]
That's not how string interpolation works.
cmd='cd %s' % (Desktop,)
First off,
cmd="'cd %s'(Desktop/)"
Doesn't seem like it would "printf" the %s.
Maybe
cmd="'cd %s/'%(Desktop)"
But I still don't know if that will interpolate since it's inside a string can using the "call" function and a python command -- wouldn't that call it on the command line?

python subprocess call OSX

I am trying to access the wifi interface through python:
In bash I can use the following
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/sbin/airport -I
-s can also be passed.
I have tried using the following in python:
from subprocess import call
call(['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/sbin/airport', '-I'])
something is definitely not correct - as I get as a reply:
Traceback (most recent call last):
File "ip3.py", line 5, in <module>
call(['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/sbin/airport', '-I'])
File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/subprocess.py", line 467, in call
return Popen(*popenargs, **kwargs).wait()
File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/subprocess.py", line 741, in __init__
restore_signals, start_new_session)
File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/subprocess.py", line 1356, in _execute_child
raise child_exception_type(errno_num, err_msg)
OSError: [Errno 2] No such file or directory: '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/sbin/airport'
Any ideas would be welcome... I just want to begin by printing this to screen, saving as an array etc...
I dont have a high enough rating to answer my own question yet, so Ill say it here!
so I was being stupid!
from subprocess import call
call(['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport', '-I'])
Works fine. Just needed to remove /usr/sbin/airport
call take first argument as command and subsequent arguments to that command.
In your case
command is,
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
and command's two arguments are,
/usr/sbin/airport
-I
So, you need to call it as,
from subprocess import call
call(['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport' '/usr/sbin/airport', '-I'])
Try like this
from subprocess import call
call(['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport', '/usr/sbin/airport', '-I'])
Otherwise it thinks /usr/sbin/airport is part of the first path.

Categories