How do you search subprocess output in Python for

2019-07-02 10:31发布

问题:

I'm trying to search through a variable's output to find a specific word, then have that trigger a response if True.

variable = subprocess.call(["some", "command", "here"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

for word in variable:
    if word == "myword":
        print "something something"

I'm sure I'm missing something big here, but I just can't figure out what it is.

Thanks in advance for setting me straight.

回答1:

You need to check the stdout of the process, you can do something like that:

mainProcess = subprocess.Popen(['python', file, param], stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
communicateRes = mainProcess.communicate() 
stdOutValue, stdErrValue = communicateRes

# you can split by any value, here is by space
my_output_list = stdOutValue.split(" ")

# after the split we have a list of string in my_output_list 
for word in my_output_list :
    if word == "myword":
        print "something something"

This is for stdout, you can check the stderr also, Also here is some info about split



回答2:

Use subprocess.check_output. That returns the standard output from the process. call only returns the exit status. (You'll want to call split or splitlines on the output.)



回答3:

First of all, you should use Popen or check_output to get the process output, and then use the communicate() method to get stdout and stderr and search for your word in these variables:

variable = subprocess.Popen(["some", "command", "here"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = variable.communicate()
if (word in stdout) or (word in stderr):
    print "something something"


回答4:

subprocess.call returns the process'es exit code, not its stdout. There's an example on this help page for how to capture a command's output. If you plan to do something more sophisticated with the subprocess, pexpect might be more convenient.



回答5:

If the output may be possibly unlimited then you shouldn't use .communicate() to avoid running out of computer memory. You could read subprocess' output line by line instead:

import re
from subprocess import Popen, PIPE

word = "myword"
p = Popen(["some", "command", "here"], 
          stdout=PIPE, universal_newlines=True)
for line in p.stdout: 
    if word in line:
       for _ in range(re.findall(r"\w+", line).count(word)):
           print("something something")

Note: stderr is not redirected. If you leave stderr=PIPE without reading from p.stderr later then the process may block forever if it generates enough output on stderr to fill its OS pipe buffer. See this answer if you want to get both stdout/stderr separately in the unlimited case.