I have the following code that is attempting to start each of the "commands" below in Linux. The module attempts to keep each of the 2 commands running if either should crash for whatever reason.
#!/usr/bin/env python
import subprocess
commands = [ ["screen -dmS RealmD top"], ["screen -DmS RealmD top -d 5"] ]
programs = [ subprocess.Popen(c) for c in commands ]
while True:
for i in range(len(programs)):
if programs[i].returncode is None:
continue # still running
else:
# restart this one
programs[i]= subprocess.Popen(commands[i])
time.sleep(1.0)
Upon executing the code the following exception is thrown:
Traceback (most recent call last):
File "./marp.py", line 82, in <module>
programs = [ subprocess.Popen(c) for c in commands ]
File "/usr/lib/python2.6/subprocess.py", line 595, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1092, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
I think I'm missing something obvious, can anyone see what's wrong with the code above?
Use ["screen", "-dmS", "RealmD", "top"] instead of ["screen -dmS RealmD top"].
Maybe also use the complete path to screen.
Only guess is that it can't find screen. Try /usr/bin/screen or whatever which screen gives you.
The problem is that your command should be split. subprocces requires that the cmd is a list, not a string.
It shouldn't be:
subprocess.call('''awk 'BEGIN {FS="\t";OFS="\n"} {a[$1]=a [$1] OFS $2 FS $3 FS $4} END
{for (i in a) {print i a[i]}}' 2_lcsorted.txt > 2_locus_2.txt''')
That won't work. If you feed subprocess a string, it assumes that that is the path to the command you want to execute. The command needs to be a list. Check out http://www.gossamer-threads.com/lists/python/python/724330. Also, because you're using file redirection, you should use subprocess.call(cmd, shell=True). You can also use shlex.
I got same error when i wrote like this :-
subprocess.Popen("ls" ,shell = False , stdout = subprocess.PIPE ,stderr = subprocess.PIPE)
And problem is solved when i made shell=True .It will work
subprocess.Popen("ls" ,shell = False , stdout = subprocess.PIPE ,stderr = subprocess.PIPE, shell=True)
commands = [ "screen -dmS RealmD top", "screen -DmS RealmD top -d 5" ]
programs = [ subprocess.Popen(c.split()) for c in commands ]
Just in case.. I also got stuck with this error and the issue was that my files were in DOS instead of UNIX so at :
return subprocess.call(lst_exp)
where lst_exp is a list of args, one of them was "not found" because it was in DOS instead of UNIX but error thrown was the same :
File "/var/www/run_verifier.py", line 59, in main
return subprocess.call(lst_exp)
File "/usr/lib/python2.7/subprocess.py", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Related
I am trying to read input from the user and store it in a variable by using subprocess.check_output in python2.7. But it shows up the error OSError: [Errno 2] No such file or directory when I try to run it. Also it is to be noted that I strictly want to use shell=False because of the security concerns.
I have tried subprocess.Popen and it doesnt work that way too.
I have tried to use sys.stdin = open('/dev/tty', 'r') and stdin=subprocess.PIPE but give the same error as above.
>>> import sys
>>> import subprocess
>>> sys.stdin = open('/dev/tty', 'r')
>>> cmd = ('read userinput && echo "$userinput"')
>>> confirmation = subprocess.check_output(cmd.split(), stdin=sys.stdin).rstrip()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 567, 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 1343, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
The expected result is that it should ask for user input and store it to the confirmation variable
You are entering a shell command (read and echo are shell built-ins, and && is shell syntax), therefore you need shell=True. This is a single shell command, so you don't use the split. The parentheses around the command in python have no effect in this case:
import sys
import subprocess
sys.stdin = open('/dev/tty', 'r')
cmd = 'read userinput && echo "$userinput"'
confirmation = subprocess.check_output(cmd, stdin=sys.stdin, shell=True).rstrip()
print'****', confirmation
Gives:
$ python gash.py
hello
**** hello
I made an attempt at parsing running programs in my computer (Debian OS) with the Subprocess python module. Here is my code:
import subprocess
cmd = "ps -A" # Unix command to get running processes
runningprox = subprocess.check_output(cmd) #returns output as byte string
rpstring = runningprox.decode("utf-8")
#converts byte string to string and puts it in a variable
print(rpstring)
However, when I run the code, I get the following error message:
Traceback (most recent call last): File "ratalert.py", line 6, in
runningprox = subprocess.check_output(cmd) #returns output as byte string File "/usr/local/lib/python3.6/subprocess.py", line 336, in
check_output
**kwargs).stdout File "/usr/local/lib/python3.6/subprocess.py", line 403, in run
with Popen(*popenargs, **kwargs) as process: File "/usr/local/lib/python3.6/subprocess.py", line 707, in init
restore_signals, start_new_session) File "/usr/local/lib/python3.6/subprocess.py", line 1333, in _execute_child
raise child_exception_type(errno_num, err_msg) FileNotFoundError: [Errno 2] No such file or directory: 'ps -A'
I don't understand why I get this error message. Considering 'ps -A' is neither a file nor a directory, but just the Unix command I put in a variable as a string.
How can I fix this? Thank you.
The subprocess.check_output function expects a list with the command and its arguments, like so:
runningprox = subprocess.check_output(['ps', '-A'])
Otherwise, it will treat the string you passed as a single command, and will look up for an executable file with name ps -A, space included and all.
You can use shlex to do the splitting as the shell would do:
import shlex, subprocess
cmd = 'ps -A'
runningprox = subprocess.check_output(shlex.split(cmd))
I am try to execute below command using python subprocess but it is failing.
Please help
import subprocess
cmd = "bash /opt/health_check -t 2>/dev/null"
retcode = subprocess.call([cmd])
print retcode
I am getting below output:
Traceback (most recent call last):
File "./script.py", line 65, in <module>
retcode = subprocess.call([cmd])
File "/usr/lib64/python2.7/subprocess.py", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
If you call check_output with a list, you would need to tokenize the command yourself, as in:
import subprocess
cmd = ["bash", "/opt/health_check", "-t"]
retcode = subprocess.call([cmd])
print retcode
This doesn't use a shell so you can't use input redirection. If you really want to execute your command with a shell, then pass a string and set shell=True:
import subprocess
cmd = "bash /opt/health_check -t 2>/dev/null"
retcode = subprocess.call(cmd, shell=True)
print retcode
This is an incorrect way to call subprocess. A quick and dirty way to do it is to change it like:
subprocess.call(cmd, shell=True)
This will invoke the system's shell to execute the command, and you'll have access to all the goodies it provides. It's not something to use ligthly, however, so check security considerations from the docs before doing so.
Otherwise, you can simply provide the command as a list, like so:
subprocess.call(["bash", "/opt/health_check"])
In my program I call the command:
command_two = 'sfit4Layer0.py -bv5 -fs'
subprocess.call(command_two.split(), shell=False)
I am using PyCharm and I get the error message:
Traceback (most recent call last):
File "part2test.py", line 5, in <module>
subprocess.call(command_two.split(), shell=False) #writes the summary file
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
When walking through my program, it never gets to the program I want it to sfit4Layer0.py, it is getting stuck in subprocess but I am not sure why. Changing the shell=True doesn't do anything helpful either - I don't get these error messages but it does not execute my code properly. Any suggestions would be helpful.
My bash profile:
PATH="~/bin:/usr/bin:${PATH}"
export PATH PYTHONPATH="/Users/nataliekille/Documents/sfit4/pbin/Layer0:/Users/nataliekille/Documents/sfit4/pbin/Layer1:/Users/nataliekille/Documents/sfit4/pbin/ModLib:/Users/nataliekille/Documents/sfit4/SpectralDB"
export PYTHONPATH
PATH=${PATH}:${PYTHONPATH}
export PATH
You've missed an important part of the subprocess documentation. "If passing a single string [at the command, rather than a list of strings], either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments."
So the kernel is compaining because there is not executable with the name 'sfit4Layer0.py -bv5 -fs'. Should work if you replace the string with (for example) 'sfit4Layer0.py -bv5 -fs'.split(), or ['sfit4Layer0.py', '-bv5', '-fs'].
I am trying to run a program to make some system calls inside Python code using subprocess.call() which throws the following error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
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 2] No such file or directory
My actual Python code is as follows:
url = "/media/videos/3cf02324-43e5-4996-bbdf-6377df448ae4.mp4"
real_path = "/home/chanceapp/webapps/chanceapp/chanceapp"+url
fake_crop_path = "/home/chanceapp/webapps/chanceapp/chanceapp/fake1"+url
fake_rotate_path = "/home/chanceapp/webapps/chanceapp.chanceapp/fake2"+url
crop = "ffmpeg -i %s -vf "%(real_path)+"crop=400:400:0:0 "+ "-strict -2 %s"%(fake_crop_path)
rotate = "ffmpeg -i %s -vf "%(fake_crop_path)+"transpose=1 "+"%s"%(fake_rotate_path)
move_rotated = "mv"+" %s"%(fake_rotate_path)+" %s"%(real_path)
delete_cropped = "rm "+"%s"%(fake_crop_path)
#system calls:
subprocess.call(crop)
Can I get some relevant advice on how to solve this?
Use shell=True if you're passing a string to subprocess.call.
From docs:
If passing a single string, either shell must be True or
else the string must simply name the program to be executed without
specifying any arguments.
subprocess.call(crop, shell=True)
or:
import shlex
subprocess.call(shlex.split(crop))
No such file or directory can be also raised if you are trying to put a file argument to Popen with double-quotes.
For example:
call_args = ['mv', '"path/to/file with spaces.txt"', 'somewhere']
In this case, you need to remove double-quotes.
call_args = ['mv', 'path/to/file with spaces.txt', 'somewhere']
Can't upvote so I'll repost #jfs comment cause I think it should be more visible.
#AnneTheAgile: shell=True is not required. Moreover you should not use
it unless it is necessary (see # valid's comment). You should pass
each command-line argument as a separate list item instead e.g., use
['command', 'arg 1', 'arg 2'] instead of "command 'arg 1' 'arg 2'". –
jfs Mar 3 '15 at 10:02