Search code examples
pythonsubprocesspopen

Python subprocess call with greater sign (>) not working


I have a executable that accepts string and outputs another string. Now I need to feed a file to it as input and write output to another file. The standard command for that is like the following executable_path < input > output. Now I wrap this in python. But I get errors.

 cmd = [executable_path , '<', 'tmp/input.txt', '>',
           'tmp/output.txt']
    p = subprocess.Popen(cmd)
    p.communicate()

invalid argument: <

I also tried joining the cmd arguments:

cmd = [executable_path, ' '.join(['<', 'tmp/input.txt', '>',
       'tmp/output.txt'])]

invalid argument: < tmp/input.txt > tmp/output.txt

Passing the command as string didn't work either.

 p = subprocess.Popen(' '.join(cmd))

OSError: [Errno 2] No such file or directory

What am I missing here?


Solution

  • subprocess.Popen() has three parameters for easy redirection: stdin, stdout and stderr. By default the subprocess retains the file descriptors of your Python instance.

    with open('tmp/input.txt', 'rb', 0) as in_stream, \
         open('tmp/output.txt', 'wb', 0) as out_stream:
        subprocess.Popen([executable_path], stdin=in_stream, stdout=out_stream)
    

    does the same as the shell command executable_path < tmp/input.txt > tmp/output.txt.

    The arguments to open() are the filename, mode and buffering. "rb" means "read binary data", "wb" means "(over)write binary data", "ab" means "append binary data".