• Uncategorized

About python : How-to-pipe-input-to-python-line-by-line-from-linux-program

Question Detail

I want to pipe the output of ps -ef to python line by line.

The script I am using is this (first.py) –

#! /usr/bin/python

import sys

for line in sys.argv:
print line

Unfortunately, the “line” is split into words separated by whitespace. So, for example, if I do

echo “days go by and still” | xargs first.py

the output I get is

./first.py
days
go
by
and
still

How to write the script such that the output is

./first.py
days go by and still

?

Question Answer

Instead of using command line arguments I suggest reading from standard input (stdin). Python has a simple idiom for iterating over lines at stdin:
import sys

for line in sys.stdin:
sys.stdout.write(line)

My usage example (with above’s code saved to iterate-stdin.py):
$ echo -e “first line\nsecond line” | python iterate-stdin.py
first line
second line

With your example:
$ echo “days go by and still” | python iterate-stdin.py
days go by and still

……………………………………………………
What you want is popen, which makes it possible to directly read the output of a command like you would read a file:

import os
with os.popen(‘ps -ef’) as pse:
for line in pse:
print line
# presumably parse line now

Note that, if you want more complex parsing, you’ll have to dig into the documentation of subprocess.Popen.
……………………………………………………
Another approach is to use the input() function (the code is for Python 3).
while True:
try:
line = input()
print(‘The line is:”%s”‘ % line)
except EOFError:
# no more information
break

The difference between the answer and the answer got by Dr. Jan-Philip Gehrcke is that now each of the lines is without a newline (\n) at the end.
……………………………………………………
I know this is really out-of-date, but you could try
#! /usr/bin/python
import sys
print(sys.argv, len(sys.argv))

if len(sys.argv) == 1:
message = input()
else:
message = sys.argv[1:len(sys.argv)]

print(‘Message:’, message)

and I tested it thus:
$ ./test.py
[‘./test.py’] 1
this is a test
Message: this is a test

$ ./test.py this is a test
[‘./test.py’, ‘this’, ‘is’, ‘a’, ‘test’] 5
Message: [‘this’, ‘is’, ‘a’, ‘test’]

$ ./test.py “this is a test”
[‘./test.py’, ‘this is a test’] 2
Message: [‘this is a test’]

$ ./test.py ‘this is a test’
[‘./test.py’, ‘this is a test’] 2
Message: [‘this is a test’]

$ echo “This is a test” | ./test.py
[‘./test.py’] 1
Message: This is a test

Or, if you wanted the message to be one string, each and every time, then
message = ‘ ‘.join(sys.argv[1:len(sys.argv)])

would do the trick on line 8

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.