Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Subprocess - How to call a Piped command in Windows?

How do I run this command with subprocess?

I tried:

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

but got:

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

Things I've noticed:

  1. Running the command on the windows console works fine.
  2. If I remove the ECHO bosco| part, it runs fine the the popen call above. So I think this problem is related to echo or |.
like image 325
Greg Avatar asked Jun 25 '09 22:06

Greg


2 Answers

First and foremost, you don't actually need a pipe; you are just sending input. You can use subprocess.communicate for that.

Secondly, don't specify the command as a string; that's messy as soon as filenames with spaces are involved.

Thirdly, if you really wanted to execute a piped command, just call the shell. On Windows, I believe it's cmd /c program name arguments | further stuff.

Finally, single back slashes can be dangerous: "\p" is '\\p', but '\n' is a new line. Use os.path.join() or os.sep or, if specified outside python, just a forward slash.

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')
like image 59
phihag Avatar answered Nov 03 '22 00:11

phihag


You were right, the ECHO is the problem. Without the shell=True option the ECHO command cannot be found.

This fails with the error you saw:

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

This passes: prints Ni and a 0

subprocess.call(["ECHO", "Ni"], shell=True)
like image 44
Jamie Czuy Avatar answered Nov 03 '22 01:11

Jamie Czuy