2014-01-20 4 views
1

Предположим, что я хочу вызвать программу theprogram в пакетном файле Windows. Код будет выглядеть так:Использование труб с модулем подпроцесса python

exit | theprogram arg1 

Я протестировал его, и он отлично работает, огромное спасибо!

Теперь, большое изменение стратегии, я должен позвонить theprogram внутри сценария python. Для этого я использую подпроцесс . Я получаю:

subprocess.call(['theprogram', arg1]) 

Но для этого, чтобы работать правильно, мне нужно это трубы с заявлением на выходе, как я сделал в пакетном файле. Конечно, это не работы

subprocess.call(['exit | theprogram', arg1]) 

Кто-нибудь знает, как я могу правильно трубы это выход заявление на вход Theprogram?

Большое спасибо!

+2

Я знаю, что это не строго связано с этим вопросом, но почему вы используете '' 'exit''' команды в вашем пакетном файле? Почему не просто '' 'python theprogram arg1'''? – wnnmaw

+1

Да, пожалуйста, объясните, почему вам нужно передать несуществующий вывод 'exit' в вашу программу. Я подозреваю, что вы получите тот же результат, используя ' dbenham

+1

Программа, которую я хотел бы выполнить, фактически является sqlplus. Когда вы запускаете его, он остается открытым, ожидая ввода команды, пока вы не попросите ее выйти (путем ввода ввода * exit *). Я не хочу вводить этот * выход * вручную каждый раз, когда я запускаю свой скрипт python, я бы предпочел, чтобы он завершился, как только это будет сделано, следовательно, трубопровод :) – Backslash36

ответ

3

Укажите аргумент shell ключевое слово для разбора вызова через оболочку:

subprocess.call('exit | theprogram %s' % arg1, shell=True) 

Конечно, это заставляет вас вручную цитировать arg1, если он содержит пробелы или метасимволы другой оболочки. Обычно это функция, которая subprocess.call не вызывает оболочку именно так, что вам не нужно беспокоиться о цитировании проблем, но в вашем случае она выбрасывает ребенка вместе с водой для ванны, потому что вы не нуждаетесь в помощи помощь раковины для оператора трубы ,

Лучшей альтернативой, которая сохраняет лучшее из обоих миров, за счет некоторого набора текста, чтобы позволить subprocess модуль для установки трубы:

p1 = subprocess.Popen(["exit"], stdout=subprocess.PIPE) 
p2 = subprocess.Popen(["theprogram", arg1], stdin=p1.stdout) 
p1.stdout.close() 
p2.communicate() 

Теперь вам не нужно скорлупу и вам не нужно беспокоиться о цитировании. Дополнительные примеры использования модуля subprocess доступны в the documentation.

+0

Это работает! Спасибо, сэр – Backslash36

0

Это не прямой ответ на ваш вопрос, но он затрагивает ошибочность вашего мышления.

Вы пытаетесь проинструктировать sql * plus к EXIT после того, как он закончит выполнение скрипта. Но это не то, что делает ваша конструкция трубопровода exit | sqlplus .... Он не просто передает строку echo в качестве входа в sqlplus. Труба выводит команду exit (ее нет) и использует ее как вход для команды справа.

Правильный способ сделать то, что вы пытаетесь использовать echo exit|sqlplus ....

Причина, по которой ваш код работает, заключается в том, что sqlplus обнаруживает, что дополнительных входных данных нет (входной буфер закрыт), поэтому он немедленно завершает работу после выполнения сценария. Вы получите тот же результат, используя любую команду слева, которая не выводит результат.Например:

(call)|sqlplus ... 

Другим вариантом является просто перенаправить ввод в NUL

<nul sqlplus ... 
Смежные вопросы