Why are Python 3 Line breaks \n not working with print and subprocess Popen stdout?


Python 3.7.1: Calling grep with subprocess.Popen to pull errors from a log file. When printing to screen, line breaks \n are not processed.

Example

a = subprocess.Popen(["grep", "ERR", "errors.log"], stdout=subprocess.PIPE)
print(a.stdout.read())

Output

ERR 1 ret: 31113\nERR 2 ret: 35523\nERR 3 ret: 3810 (etc.)

Can't imagine why the line breaks are not processed. I would expect this:

ERR 1 ret: 31113
ERR 2 ret: 35523
ERR 3 ret: 3810
(etc.)

Been combing the 'net for answers, but no luck. Thx :^)

References:

How would I specify a new line in Python?
Python Popen grep


Answer

Popen standard output and errors are bytes per default. Printing bytes doesn't try to print the linefeeds as such, but prints their representation instead.

Prior to 3.5, you cannot use encoding, but you can certainly decode the output to string using bytes.decode:

a = subprocess.Popen(["grep", "ERR", "errors.log"], stdout=subprocess.PIPE)
print(a.stdout.read().decode())

(decode can need an argument depending on the contents of the file)