4

The gist of what I'm trying to do is this:

grep -n "some phrase" {some file path} | head -1

I would like to pass the output of this into python. What I've tried so far is:

p = subprocess.Popen('grep -n "some phrase" {some file path} | head -1',shell=True,stdout=subprocess.PIPE)

I get back a lot of messages saying

"grep: writing output: Broken pipe"

I'm not very familiar with the subprocess module, I would like advice as to how to get this output, and what I am currently doing wrong.

Mazdak
  • 105,000
  • 18
  • 159
  • 188
user2380153
  • 173
  • 1
  • 8

2 Answers2

5

The docs show you how to replace shell piping using Popen:

from subprocess import PIPE, Popen


p1 = Popen(['grep', '-n', 'some phrase', '{some file path}'],stdout=PIPE)
p2 = Popen(['head', '-1'], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
out,err = output = p2.communicate()
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • @user3467349, he/she seems to want to get the line number that some phrase is on which is what out should return. Either way you need to pass the output of process 1 to the input of process 2 to replicate the pipeline. – Padraic Cunningham Jan 26 '15 at 16:58
  • Thanks so much. So if I would have to pipe it through multiple things in the shell, I could create a new Popen for each of those. – user2380153 Jan 26 '15 at 20:19
  • Yes exactly. All it is doing basically is sending the output of one process into the input of another. – Padraic Cunningham Jan 26 '15 at 20:40
1

Let shell do it for you (lazy workaround):

import subprocess
p = subprocess.Popen(['-c', 'grep -n "some phrase" {some file path} | head -1'], shell=True, stdout=subprocess.PIPE)
out, err = p.communicate()
print out, err
Dmitry Nedbaylo
  • 2,254
  • 1
  • 20
  • 20