Ian Zane
Ian Zane

Reputation: 2389

Monitoring the shell through python

Quick and simple: I'm calling a process with subprocess.popen which will run continuously in cmd/terminal. I want to call a function if a certain string of text is displayed in cmd/terminal. How would I do this? I'm rather new to python, so the simplest solution will probably be the best one.

Thank you very much!

Upvotes: 1

Views: 227

Answers (2)

Viktor Kerkez
Viktor Kerkez

Reputation: 46586

The only problem with @unutbu code is (but that doesn't apply to your case, it's more in general) is that it blocks your application on every readline call. So you cannot do anything else.

If you want a nonblocking solution you should create a file, open it in the write and read mode, pass the writer to Popen and read from the reader. Reading from the reader will always be non-blocking.

import io
import time
import subprocess

filename = 'temp.file'
with io.open(filename, 'wb') as writer, io.open(filename, 'rb', 1) as reader:
    process = subprocess.Popen(command, stdout=writer)
    # Do whatever you want in your code
    data = reader.read() # non-blocking read
    # Do more stuff
    data = reader.read() # another non-blocking read...
    # ...

And so on...

This doesn't apply for your particular case in which the @unutbu's solution works perfectly well. I added it just for completeness sake...

Upvotes: 1

unutbu
unutbu

Reputation: 879421

The output you are looking for is either coming from stdout or stderr. Let's assume it's coming from stdout. (If it is coming from stderr the solution is analogous; just change stdout to stderr, below.)

import subprocess
PIPE = subprocess.PIPE

proc = subprocess.Popen(['ls'], stdout=PIPE)
for line in iter(proc.stdout.readline, ''):
    if line.startswith('a'):
        print(line)

Replace line.startswith('a') with whatever condition is appropriate, and (of course) replace ['ls'] with whatever command you desire.

Upvotes: 3

Related Questions