2017-02-09 34 views
1

Я пытаюсь назначить задачи qsub из скрипта python.Python: echo with subprocess

До сих пор я всегда был с помощью таких выражений для представления qsub:

echo "python script.py arg1 arg2" | qsub 

Я попытался воспроизвести эту команду в питоне:

command = 'echo "python sub_master_script.py ' + str(i) + ' ' + path + '" | qsub -pe make 5 -N Teaching_' + str(i) + ' -cwd' 
subprocess.call(shlex.split(command)) 

Хотя command несет команду я обычно использовать, он интерпретируется как простой echo при запуске скрипта python.

И вместо того, чтобы начать новую работу, я получаю это написано в консоли:

python sub_master_script.py 0.75 /data5/bio/runs-galkin/Iterative/test_OTU.txt | qsub -pe make 5 -N Teaching_0.75 -cwd 

Почему это происходит? Как я могу заставить его работать?

ответ

2

Вы сильно используете возможности оболочки, в основном, запустив вместе два процесса.

subprocess.call(shlex.split(command),shell=True) 

- срочный.

Правильный способ сделать это было бы использовать 1 subprocess.Popen экземпляр, обеспечивают вход через communicate (для имитации echo python ...) и падение shell=True (с использованием pipes.quote, как Чарльз заметил, чтобы убедиться, что строки цитироваться при необходимости)

import pipes 
input_string = "python sub_master_script.py {} {}\n".format(*(map(pipes.quote,[str(i),path]))) 

p = subprocess.Popen(['qsub','-pe','make','5','-N','Teaching_{}'.format(i),'-cwd'],stdin=subprocess.PIPE) 
out,err = p.communicate(input_string) 
+0

Это предполагает, что 'i' и' path' являются строками, которые не нужно указывать/экранировать. Использование 'pipe.quote()' для подготовки их значений было бы более безопасным (хотя, предоставлено, исходная команда оболочки OP небезопасна/багги точно так же). –

+0

@CharlesDuffy nice add-on. Ред. –

+0

Я попытался использовать ваше решение, и я получаю 'TypeError: __init __() получил неожиданный аргумент ключевого слова 'input'' Использование' subprocess.Popen (command, shell = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) ' работает отлично. Я не вижу, что случилось с 'shell = True', поэтому я думаю, что я оставлю это – lotrus28