Python Forum
Subprocess - get only first few lines of stdout - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Subprocess - get only first few lines of stdout (/thread-3516.html)



Subprocess - get only first few lines of stdout - j.crater - May-30-2017

Hello all. I am using subprocess module to execute a process and read stdout returned by it. Currently my code saves all the lines of stdout to a list ("lines" in the code below). However, I am interested only in first 3 lines of the stdout. The only way I managed to get first 3 lines was by simply taking first 3 items from the list. But I am wondering whether there is a more elegant and efficient way. One which would only have subprocess "extract" a specific number of stdout lines already to start with? Thanks. JC

process = subprocess.Popen("top -n 1", stdout=subprocess.PIPE, shell=True)
output = process.stdout.read()
output_lines = output.split(b'\n')
lines = []



RE: Subprocess - get only first few lines of stdout - snippsat - May-30-2017

stdout will give all contend at once so,so split at \n is okay.
You should pretty much never use shell=True(security reasons).
Popen(['top', '-n', 1], stdout=subprocess.PIPE)

For Python 2.7 or newer versions can use check_output(),to cacth the output.
Example:
from subprocess import check_output

# Windows
out = check_output(['ping', 'google.com'])
# linux
#out = check_output(['ping', '-c', '4', 'google.com'])
print(out.decode('utf-8').strip())
Output:
Pinging google.com [108.177.14.102] with 32 bytes of data: Reply from 108.177.14.102: bytes=32 time=63ms TTL=48 Reply from 108.177.14.102: bytes=32 time=64ms TTL=48 Reply from 108.177.14.102: bytes=32 time=63ms TTL=48 Reply from 108.177.14.102: bytes=32 time=63ms TTL=48 Ping statistics for 108.177.14.102:    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds:    Minimum = 63ms, Maximum = 64ms, Average = 63ms
Get 3 first lines,if look at output there also a \r
So then is:
Output:
>>> output = out.decode('utf-8').strip() >>> output.split('\r\n')[0:3] ['Pinging google.com [64.233.165.139] with 32 bytes of data:', 'Reply from 64.233.165.139: bytes=32 time=63ms TTL=48', 'Reply from 64.233.165.139: bytes=32 time=63ms TTL=48']



RE: Subprocess - get only first few lines of stdout - j.crater - May-30-2017

Thanks, this is very nice :) Especially security tips (though honestly I know far too little to have an understanding of it).
Soon after I posted this I noticed you gave a similar reply in another thread.

I am on Linux, Python 3.5. How did you know/decide to use decode('utf-8'), and not 'ascii' for example?


RE: Subprocess - get only first few lines of stdout - snippsat - May-30-2017

(May-30-2017, 07:26 PM)j.crater Wrote: How did you know/decide to use decode('utf-8'), and not 'ascii' for example?
Python 3 represents strings as Unicode,and will not take in data without encoding(will be bytes string if try).
If have bytes,we can decode them to a Unicode string using UTF-8.
>>> b = b'hello'
>>> type(b)
<class 'bytes'>
>>> c = b.decode('utf-8') # Just b.decode() will do the same
>>> c
'hello'
>>> type(c)
<class 'str'>
Unicode was one biggest changes moving from Python 2 to Python 3.
Python 3 has UTF-8 as default encoding,Python 2 had ASCII as default encoding.