38

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?

2
  • 2
    you should use programs[i].poll() instead of programs[i].returncode. Commented Nov 22, 2012 at 16:02
  • related: subprocess.call using string vs using list Commented Dec 16, 2015 at 18:38

6 Answers 6

66

Use ["screen", "-dmS", "RealmD", "top"] instead of ["screen -dmS RealmD top"].

Maybe also use the complete path to screen.

Sign up to request clarification or add additional context in comments.

6 Comments

Docs say a string or a sequence can be used.
commands = [ ["screen", "-dmS", "RealmD", "top"], ["screen", "-DmS", "RealmD", "top", "-d", "5"] ] Worked perfectly!
@colin: In this case a sequence was used and it needs to contain the parameters separately. Probably a simple string (without the []) would also work.
Either 1 string, or 1 parameter "word" per element of a list. If you pass a sequence, you should have done the exact parsing that a shell normally does. If you pass a single string it's parsed exactly the way the shell would have parsed it.
@umpirsky: from the docs: "On Unix, if args is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done _if not passing arguments to the program_."
|
9

Only guess is that it can't find screen. Try /usr/bin/screen or whatever which screen gives you.

1 Comment

Yep, this was my issue. Command was not in system path as expected.
7

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.

2 Comments

subprocess.call("executable -parameter 1 -hello", shell=True) works (assuming it is in the PATH of the shell)
It depends on the call. If you do not parse input then it is as safe as a shell command.
3

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)

Comments

2
commands = [ "screen -dmS RealmD top", "screen -DmS RealmD top -d 5" ]
programs = [ subprocess.Popen(c.split()) for c in commands ]

1 Comment

Use shlex.split() instead of string.split()
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.