2009-06-25 4 views
5

Как запустить эту команду с подпроцессом?Python - Subprocess - Как вызвать команду Piped в Windows?

Я пробовал:

proc = subprocess.Popen(
    '''ECHO bosco|"C:\Program Files\GNU\GnuPG\gpg.exe" --batch --passphrase-fd 0 --output "c:\docume~1\usi\locals~1\temp\tmptlbxka.txt" --decrypt "test.txt.gpg"''', 
    stdin=subprocess.PIPE, 
    stdout=subprocess.PIPE, 
    stderr=subprocess.STDOUT, 
) 
stdout_value, stderr_value = proc.communicate() 

но получил:

Traceback (most recent call last): 
... 
    File "C:\Python24\lib\subprocess.py", line 542, in __init__ 
    errread, errwrite) 
    File "C:\Python24\lib\subprocess.py", line 706, in _execute_child 
    startupinfo) 
WindowsError: [Errno 2] The system cannot find the file specified 

вещи я заметил:

  1. Запуск команды на окнах консоли прекрасно работает.
  2. Если я удалю ECHO bosco | часть, он отлично работает вышеприведенный вызов. Поэтому я думаю, что эта проблема связана с эхом или |.
+0

ли это полная линия на самом деле работает, когда вы запускаете его в консоли Windows? WindowsError предполагает, что проблема не в коде Python, а в действительной команде. –

+0

Да, он запускается из консоли dos dos. – Greg

ответ

11

Прежде всего, вам действительно не нужна труба; вы просто отправляете ввод. Вы можете использовать для этого subprocess.communicate.

Во-вторых, не указывайте команду как строку; это грязно, как только имена файлов с пробелами.

В-третьих, если вы действительно хотите выполнить команду с каналами, просто вызовите оболочку. В Windows я считаю, что это cmd /c program name arguments | further stuff.

И, наконец, одна косая черта может быть опасной: "\p" - '\\p', но '\n' - это новая линия. Используйте os.path.join() или os.sep или, если указано вне python, просто косую черту.

proc = subprocess.Popen(
    ['C:/Program Files/GNU/GnuPG/gpg.exe', 
    '--batch', '--passphrase-fd', '0', 
    '--output ', 'c:/docume~1/usi/locals~1/temp/tmptlbxka.txt', 
    '--decrypt', 'test.txt.gpg',], 
    stdin=subprocess.PIPE, 
    stdout=subprocess.PIPE, 
    stderr=subprocess.STDOUT, 
) 
stdout_value, stderr_value = proc.communicate('bosco') 
+0

Спасибо, это сработало! – Greg

4

Вы были правы, проблема ECHO. Без опции shell = True команда ECHO не может быть найдена.

Это терпит неудачу с ошибкой вы видели:

subprocess.call(["ECHO", "Ni"]) 

Пропускает: печатает Ni и 0

subprocess.call(["ECHO", "Ni"], shell=True) 
+0

На самом деле, это не должно быть 'subprocess.call (" ECHO Ni ", shell = True)'? и 'subprocess.call ([" ECHO "," Ni "])' отлично работает для меня. – Chris

+0

Вы можете использовать либо в соответствии с [Popen Constructor] (https://docs.python.org/3/library/subprocess.html#popen-constructor) docs: «Если не указано иное, рекомендуется передавать аргументы как последовательность ». –