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