Using Python's subprocess.call to kill firefox process - python

I am trying to kill any firefox processes running on my system as part of a python script, using the script below:
if subprocess.call( [ "killall -9 firefox-bin" ] ) is not 0:
self._logger.debug( 'Firefox cleanup - FAILURE!' )
else:
self._logger.debug( 'Firefox cleanup - SUCCESS!' )
I am encountering the following error as shown below, however 'killall -9 firefox-bin' works whenever I use it directly in the terminal without any errors.
Traceback (most recent call last):
File "./pythonfile", line 109, in __runMethod
if subprocess.call( [ "killall -9 firefox-bin" ] ) is not 0:
File "/usr/lib/python2.6/subprocess.py", line 478, in call
p = Popen(*popenargs, **kwargs)
File "/usr/lib/python2.6/subprocess.py", line 639, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Am I missing something or should I be trying to use a different python module altogether?

You need to separate the arguments when using subprocess.call:
if subprocess.call( [ "killall", "-9", "firefox-bin" ] ) > 0:
self._logger.debug( 'Firefox cleanup - FAILURE!' )
else:
self._logger.debug( 'Firefox cleanup - SUCCESS!' )
call() normally does not treat your command like the shell does, and it won't parse it out into the separate arguments. See frequently used arguments for the full explanation.
If you must rely on shell parsing of your command, set the shell keyword argument to True:
if subprocess.call( "killall -9 firefox-bin", shell=True ) > 0:
self._logger.debug( 'Firefox cleanup - FAILURE!' )
else:
self._logger.debug( 'Firefox cleanup - SUCCESS!' )
Note that I changed your test to > 0 to be clearer about the possible return values. The is test happens to work for small integers due to an implementation detail in the Python interpreter, but is not the correct way to test for integer equality.

Related

Cannot perform subprocess.run inside a snap

In my snap (coded in python), I try to perform some sudo commands but it didn’t work. Here is an example of a command that didn’t work:
command = "sudo netmgr -i country_code set:" + countryCode
subprocess.run([command])
And when I run the snap in my device it won’t work and I got this error:
> Traceback (most recent call last): File
> “/snap/iotr-configuration/x17/bin/iotr-configuration”, line 11, in
> load_entry_point(‘iotr-configure==0.0.3’, ‘console_scripts’,
> ‘iotr-configuration’)() File
> “/snap/iotr-configuration/x17/lib/python3.5/site-packages/src/app.py”,
> line 53, in main configuration_program() File
> “/snap/iotr-configuration/x17/lib/python3.5/site-packages/src/app.py”,
> line 37, in configuration_program
> confNIC.set_nic_settings(“fd05:a40b:b47d:7340::4”, “1250”) File
> “/snap/iotr-configuration/x17/lib/python3.5/site-packages/src/configureNic.py”,
> line 16, in set_nic_settings subprocess.run([command]) File
> “/snap/iotr-configuration/x17/usr/lib/python3.5/subprocess.py”, line
> 693, in run with Popen(*popenargs, **kwargs) as process: File
> “/snap/iotr-configuration/x17/usr/lib/python3.5/subprocess.py”, line
> 947, in init restore_signals, start_new_session) File
> “/snap/iotr-configuration/x17/usr/lib/python3.5/subprocess.py”, line
> 1551, in _execute_child raise child_exception_type(errno_num, err_msg)
> FileNotFoundError: [Errno 2] No such file or directory: ‘sudo netmgr
> -i country_code set:1250’
This function exist because when I type it directly in the terminal, it works…
Can you help me on this issue ?
You're calling subprocess.run in the wrong way. You should either pass it a the command as a single string (like you're doing here) but then set shell=True, or break the command into several arguments, as in:
command = ["sudo", "netmgr", "-i", "country_code", "set:" + countryside]
subprocess.run(command)
See the FAQ part of the documentation:
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.

subprocess.check_output(): OSError file not found in Python

Executing following command and its variations always results in an error, which I just cannot figure out:
command = "/bin/dd if=/dev/sda8 count=100 skip=$(expr 19868431049 / 512)"
print subprocess.check_output([command])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 566, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
WHich file it is referring to ? other commands like ls,wc are running correctly though, the command is also running well on terminal but not python script.
Your command is a list with one element. Imagine if you tried to run this at the shell:
/bin/'dd if='/dev/'sda8 count=100 skip=$(expr 19868431049 '/' 512)'
That's effectively what you're doing. There's almost certainly no directory named dd if= in your bin directory, and there's even more almost certainly no dev directory under that with an sd8 count=100 skip=$(expr 19868431049 directory with a program named 512 in it.
What you want is a list where each argument is its own element:
command = ['/bin/dd', 'if=/dev/sda8', 'count=100', 'skip=$(expr 19868431049 / 512)']
print subprocess.check_output(command) # notice no []
But that brings us to your second problem: $(expr 19868431049 / 512) isn't going to be parsed by Python or by dd; that's bash syntax. You can, of course, just do the same thing in Python instead of in bash:
command = ['/bin/dd', 'if=/dev/sda8', 'count=100',
'skip={}'.format(19868431049 // 512)]
print subprocess.check_output(command)
Or, if you really want to use bash for no good reason, pass a string, rather than a list, and use shell=True:
command = "/bin/dd if=/dev/sda8 count=100 skip=$(expr 19868431049 / 512)"
print subprocess.check_output(command, shell=True) # still no []
Although that still isn't going to work portably, because the default shell is /bin/sh, which may not know how to handle bashisms like $(…) (and expr, although I think POSIX requires that expr exist as a separate process…). So:
command = "/bin/dd if=/dev/sda8 count=100 skip=$(expr 19868431049 / 512)"
print subprocess.check_output(command, shell=True, executable='/bin/bash')
This worked for me using subprocess.popen
command = "echo $JAVA_HOME"
proc = subprocess.Popen(command,stdout=subprocess.PIPE,shell=True)

subprocess.call() for shell program which write a file

I need to execute a shell script using python. Output of shell program is a text file. No inputs to the script. Help me to resolve this.
def invokescript( shfile ):
s=subprocess.Popen(["./Script1.sh"],stderr=subprocess.PIPE,stdin=subprocess.PIPE);
return;
invokescript("Script1.sh");
On using above code., I receive the following error.
Traceback (most recent call last):
File "./test4.py", line 12, in <module>
invokescript("Script1.sh");
File "./test4.py", line 8, in invokescript
s=subprocess.Popen(["./Script1.sh"],stderr=subprocess.PIPE,stdin=subprocess.PIPE);
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 8] Exec format error
Thanks in advance...
Try this:
import shlex
def invokescript(shfile):
return subprocess.Popen(
shlex.split(shfile),
stderr=subprocess.PIPE,
stdin=subprocess.PIPE
)
invokescript("Script1.sh");
And add #!/usr/bin/env bash to your bash file of course.
I used os.system() to call shell script. This do what i expected. Make sure that you have imported os module in your python code.
invokescript( "Script1.sh" ) // Calling Function
function invokescript( shfile ): // Function Defenition
os.system("/root/Saranya/Script1.sh")
return;
following is also executable:
invokescript( "Script1.sh" ) // Calling Function
function invokescript( shfile ): // Function Defenition
os.system(shfile)
return;
Thanks for your immediate response guys.

Popen error: "[Errno 2] No such file or directory" when calling shell function

I have some custom commands.
This works:
subprocess.Popen(['python'], stdout=subprocess.PIPE)
But if I have my own system commands like deactivate, I get that error
Traceback (most recent call last):
File "runner2.py", line 21, in <module>
main()
File "runner2.py", line 18, in main
subprocess.Popen(['deactivate',], stdout=subprocess.PIPE)
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Let alone I need to execute this under my sandbox virtualenv.
Try add an extra parameter shell=True to the Popen call.
Just a note. shell=True was likely the correct solution to the o.p., since they did not make the following mistake, but you can also get the "No such file or directory" error if you do not split up your executable from its arguments.
import subprocess as sp, shlex
sp.Popen(['echo 1']) # FAILS with "No such file or directory"
sp.Popen(['echo', '1']) # SUCCEEDS
sp.Popen(['echo 1'], shell=True) # SUCCEEDS, but extra overhead
sp.Popen(shlex.split('echo 1')) # SUCCEEDS, equivalent to #2
Without shell=True, Popen expects the executable to be the first element of args, which is why it fails, there is no "echo 1" executable. Adding shell=True invokes your system shell and passes the first element of args to the shell. i.e. for linux, Popen(['echo 1'], shell=True) is equivalent to Popen('/bin/sh', '-c', 'echo 1') which is more overhead than you may need. See Popen() documentation for cases when shell=True is actually useful.
You have to give the full path to your program deactivate and then it the subprocess module should be able to find it.
I'm spawning subprocesses like that:
SHUTDOWN_CMD = os.path.sep.join(["c:", "windows", "system32", "shutdown.exe"])
def abortShutdown():
os.spawnv(os.P_NOWAIT, SHUTDOWN_CMD,
[SHUTDOWN_CMD, '/A'])
time.sleep(3)
I'm not using subprocess since Python 2.5 does not support it. I had to use use the FULL path to have it working and I guess you also have to use the full path to your custom commands.

How to determine subprocess.Popen() failed when shell=True

Windows version of Python 2.6.4: Is there any way to determine if subprocess.Popen() fails when using shell=True?
Popen() successfully fails when shell=False
>>> import subprocess
>>> p = subprocess.Popen( 'Nonsense.application', shell=False )
Traceback (most recent call last):
File ">>> pyshell#258", line 1, in <module>
p = subprocess.Popen( 'Nonsense.application' )
File "C:\Python26\lib\subprocess.py", line 621, in __init__
errread, errwrite)
File "C:\Python26\lib\subprocess.py", line 830, in
_execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
But when shell=True, there appears to be no way to determine if a Popen() call was successful or not.
>>> p = subprocess.Popen( 'Nonsense.application', shell=True )
>>> p
>>> subprocess.Popen object at 0x0275FF90>>>
>>> p.pid
6620
>>> p.returncode
>>>
Ideas appreciated.
Regards,
Malcolm
returncode will work, although it will be None until you've called p.poll(). poll() itself will return the error code, so you can just do
if a.poll() != 0:
print ":("
In the first case it fails to start, in the second - it successfully starts shell which, in turn, fails to execute the application. So your process has been properly spawned, exited and waits for you to inquire about its exit code. So, the thing is, unless your shell or environment (e.g. no memory) is utterly broken there's no way Popen itself may fail.
So, you can safely .poll() and .wait() on it to get all the sad news.

Categories

Resources