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
?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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 linensecond 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
Method 2
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.
Method 3
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.
Method 4
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
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0