search for substring in output, then print the line
Question: I would like to list a file and then search the lines for a pattern, like I do
in Bash with.

    
    
    cat /etc/passwd | grep nologin
    

I try the following:

    
    
    #!/usr/bin/python3
    
    import subprocess
    
    CMD=('cat', '/etc/passwd')
    SEARCH="nologin"
    PIPE_ERG=subprocess.Popen(CMD , stdout=subprocess.PIPE)
    OUTPUT = PIPE_ERG.communicate()[0].splitlines()
    for LINE in OUTPUT:
      if SEARCH in LINE:
        print(LINE)
    

If I execute the script with python3 I always get this errormessage:

    
    
    Traceback (most recent call last):
      File "./pipe2.py", line 11, in <module>
        if SEARCH in LINE:
    TypeError: 'str' does not support the buffer interface
    

When I just print the lines without search, the script will list all my lines.

How do I get each line with the pattern "nologin" from the output?


Answer: Looks like in Python 3,
[`PIPE_ERG.communicate()[0]`](https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate)
is not a `str`, but `bytes`, and for `bytes`, the `in` operator is not
defined. You have to convert those `bytes` to `str` first. The simplest way
would be just to do `LINE = str(LINE)` in the loop, or use `LINE.decode()`:

    
    
    for LINE in OUTPUT:
        LINE = LINE.decode()
        if SEARCH in LINE:
            print(LINE)
    

Or use `Popen` with
[`universal_newlines=True`](https://docs.python.org/3/library/subprocess.html#subprocess.check_output):

    
    
    PIPE_ERG=subprocess.Popen(CMD , stdout=subprocess.PIPE, universal_newlines=True)
    

From the documentation:

> By default, this function will return the data as encoded bytes. The actual
> encoding of the output data may depend on the command being invoked, so the
> decoding to text will often need to be handled at the application level.
>
> This behaviour may be overridden by setting universal_newlines to True

