2009-05-23 4 views
34

У меня есть следующий код, который пытается запустить каждую из «команд» ниже в Linux. Модуль пытается сохранить каждую из двух команд, если по какой-либо причине произойдет сбой.Python OSError: [Errno 2]

#!/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) 

После выполнения кода следующее исключение брошено:

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 

Я думаю, что я что-то очевидное отсутствует, может кто-нибудь увидеть, что случилось с выше код?

+2

вы должны использовать 'программы [я] .poll()' вместо 'программ [я]. returncode'. – jfs

+0

related: [subprocess.call using string vs using list] (http://stackoverflow.com/q/15109665/4279) – jfs

ответ

63

Использовать ["screen", "-dmS", "RealmD", "top"] вместо ["screen -dmS RealmD top"].

Возможно также использовать полный путь до screen.

Если программа по-прежнему не найдена, вы также можете пройти через свою оболочку с помощью shell=True, но тогда вам нужно указать и избежать ваших параметров и т. Д. Обязательно прочтите information in the docs, если вы планируете это сделать.

+1

Документы говорят, что может использоваться строка или последовательность. –

+0

команд = [["экран", "-dmS", "RealmD", "top"], ["screen", "-DmS", "RealmD", "top", "-d", "5"] ] Работал отлично! – Caedis

+0

@colin: В этом случае была использована последовательность, и она должна содержать параметры отдельно. Вероятно, также будет работать простая строка (без []). – sth

7

Только угадайте, что он не может найти screen. Попробуйте /usr/bin/screen или что угодно which screen дает вам.

7

Проблема в том, что ваша команда должна быть разделена. subprocces требует, чтобы cmd был списком, а не строкой. Это не должно быть:

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''') 

Это не будет работать. Если вы подаете подпроцесс строку, он предполагает, что это путь к команде, которую вы хотите выполнить. Команда должна быть списком. Выезд http://www.gossamer-threads.com/lists/python/python/724330. Кроме того, поскольку вы используете перенаправление файлов, вы должны использовать subprocess.call(cmd, shell=True). Вы также можете использовать shlex.

+0

'subprocess.call (" executable -parameter 1 -hello " , shell = True) 'работает (если он находится в PATH оболочки) – WoJ

+0

@WoJ: Я бы не рискнул ... – refi64

+0

Это зависит от вызова. Если вы не разбираете ввод, это безопасно, как команда оболочки. – WoJ

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

Используйте 'shlex.split()' вместо 'string.split()' –

0

Только в случае .. я застрял с этой ошибкой, и вопрос в том, что мои файлы были в DOS вместо UNIX так на:

return subprocess.call(lst_exp) 

где lst_exp список аргументов, один из них был «не найден», потому что это было в DOS вместо UNIX, но ошибка брошена была та же:

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 
1

я получил ту же ошибку, когда я писал так: -

subprocess.Popen("ls" ,shell = False , stdout = subprocess.PIPE ,stderr = subprocess.PIPE) 

И проблема решена, когда я сделал оболочки = True .Это будет работать

subprocess.Popen("ls" ,shell = False , stdout = subprocess.PIPE ,stderr = subprocess.PIPE, shell=True)

Смежные вопросы