How to use `subprocess` command with pipes

Question:

I want to use subprocess.check_output() with ps -A | grep 'process_name'.
I tried various solutions but so far nothing worked. Can someone guide me how to do it?

Asked By: zuberuber

||

Answers:

To use a pipe with the subprocess module, you have to pass shell=True.

However, this isn’t really advisable for various reasons, not least of which is security. Instead, create the ps and grep processes separately, and pipe the output from one into the other, like so:

ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
ps.wait()

In your particular case, however, the simple solution is to call subprocess.check_output(('ps', '-A')) and then str.find on the output.

Answered By: Taymon

Or you can always use the communicate method on the subprocess objects.

cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)

The communicate method returns a tuple of the standard output and the standard error.

Answered By: jkalivas

You can try the pipe functionality in sh.py:

import sh
print sh.grep(sh.ps("-ax"), "process_name")
Answered By: amoffat

Also, try to use 'pgrep' command instead of 'ps -A | grep 'process_name'

Answered By: Shooe

See the documentation on setting up a pipeline using subprocess: http://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline

I haven’t tested the following code example but it should be roughly what you want:

query = "process_name"
ps_process = Popen(["ps", "-A"], stdout=PIPE)
grep_process = Popen(["grep", query], stdin=ps_process.stdout, stdout=PIPE)
ps_process.stdout.close()  # Allow ps_process to receive a SIGPIPE if grep_process exits.
output = grep_process.communicate()[0]
Answered By: AlcubierreDrive
command = "ps -A | grep 'process_name'"
output = subprocess.check_output(["bash", "-c", command])
Answered By: Brent

Using input from subprocess.run you can pass the output of one command into a second one.

import subprocess
    
ps = subprocess.run(['ps', '-A'], check=True, capture_output=True)
processNames = subprocess.run(['grep', 'process_name'],
                              input=ps.stdout, capture_output=True)
print(processNames.stdout.decode('utf-8').strip())
Answered By: anaken78
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.