I have a flag in my Python script which specifies whether I setup and use an external process or not. This process is a command called my_command
and it takes data from standard input. If I was to run this on the command-line, it would be something like:
$ my_command < data > result
I want to use a Python script to generate lines of data
by modifying standard input and feeding it to my_command
.
I'm doing something like this:
import getopt, sys, os, stat, subprocess
# for argument's sake, let's say this is set to True for now
# in real life, I use getopt.getopt() to decide whether this is True or False
useProcess = True
if useProcess:
process = subprocess.Popen(['my_command'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
for line in sys.stdin:
# parse line from standard input and modify it
# we store the result in a variable called modified_line
modified_line = line + "foo"
# if we want to feed modified_line to my_command, do the following:
if useProcess:
process.stdin.write(modified_line)
# otherwise, we just print the modified line
else:
print modified_line
However, my_command
behaves as if it does not receive any data and quits with an error state. What am I doing wrong?
EDIT
Let's say my Python script is called my_Python_script
. Let's say I would normally pass my_command
a file called data
over standard input:
$ my_command < data > result
But now I'm passing it to my_Python_script
instead:
$ my_Python_script < data > some_other_result
I want my_Python_script
to conditionally set up a subprocess that runs my_command
on the contents of data
(which are modified by my_Python_script
before being passed to my_command
). Does this make more sense?
If I was using bash
as a scripting language, I would conditionally decide to run one of two functions. One would pipe lines of data to my_command
. The other would not. Can this be done with Python?
The readAll() method reads all remaining input on standard input and returns it as a string. As an example, the following code fragment reads all of the remaining tokens from standard input and returns them as an array of strings. String[] words = StdIn. readAllStrings();
How to Start a Process in Python? To start a new process, or in other words, a new subprocess in Python, you need to use the Popen function call. It is possible to pass two parameters in the function call. The first parameter is the program you want to start, and the second is the file argument.
The sys. stdin is another way is to read from the standard input the calls input() function internally. Python has another module named fileinput for reading the standard input. The input() function of this module can be used to read standard input or read content from one or more files.
After writing to the stdin, you need to close it:
process.stdin.write(modified_line)
process.stdin.close()
I failed to notice that the process.stdin.write()
was executed in a for loop. In which case, you should move the process.stdin.close()
to outside the loop.
Also, Raymond mentioned that we should call process.wait()
as well. So the updated code should be:
for ...
process.stdin.write(modified_line)
process.stdin.close()
process.wait()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With