Xyltic
Xyltic

Reputation: 123

How to fix "Tail: Write Error: Broken Pipe" in running linux command in Python?

I am trying to print line-by-line per file that is inside a list. At the end of each line of the file, it needs to check if the term ".sh" is in it or not.

I am getting the error

"Tail: Write error: "Broken Pipe"

Expected result:

  1. Read each from list
  2. Check each line of the file if the term ".sh" comes in it at the end of the line of the file.
  3. Prints if it finds the ".sh"

This is what I have atm:

# Modules
import os
from pprint import pprint

# Files in list
dirlist = ['test.txt','test2.txt','test3.txt']

# Loop to read the file in list
for x in range (len(dirlist)):
    print ("Output of Filename: " + dirlist[x]

# Variable to save the last 3 characters of the line
last3 = os.popen ("cat " + dirlist[x] + " | tail -c 3")
print last3

# Read file
f = open(dirlist[x], "r")
# Loop to check if the keyword is the same as last3
for l in f:
    if last3 in l:
        print ("FOUND IT!")

    else:
        print ("NOT IN IT!")

Outcome: enter image description here

@Nic

enter image description here

[![enter image description here][3]][3]

Upvotes: 1

Views: 3652

Answers (4)

Xyltic
Xyltic

Reputation: 123

With the help Of @Nic Wanavit and Daniel Pyrden, I finally fixed it.

I've put the if/else inside the loop, otherwise it would check all the lines for the .sh instead of per line.

and I've put parenthesis inside the ".sh" section and that worked!

However, I did not do it in the last 3 characters, because the -1: wasn't working for me for some reason.

# Files in List
dirlist = ['test.txt', 'test2.txt', 'test3.txt']

# Loop to read the file in list
for x in dirlist:
 print ("Output of filename: "+  x)

 with open(x) as f:
  lines = f.readlines()
  for line lines:
   print ("Line in file: " + line)

   if (".sh" in line):
    print ("FOUND IT")

   else:
    print ("not found it \n")

Result

enter image description here

Upvotes: -1

Nic Wanavit
Nic Wanavit

Reputation: 2683

I suggest that you use with environment with native python code instead of open and os.popen

Here is an example

# Files in list
dirlist = ['test.txt','test2.txt','test3.txt']

# Loop to read the file in list
for x in dirlist:
    print ("Output of Filename: " + x)
    with open(x) as f
        lines=f.readlines()
        for line in lines: #here you print each line
            print (line)

        if '.sh' in lines[-1:]: #check if .sh is in the last line
            print("found it")
        else:
            print("didnt find it")

Upvotes: 2

Daniel Pryden
Daniel Pryden

Reputation: 60947

tail (actually stdio) gives the "Broken Pipe" error when it tries to write output but there's nobody around to read it. (More specifically, when it receives SIGPIPE.)

If you're going to launch a child process with popen, you need to finish reading from the pipe before your program exits.

In your case, you should probably use subprocess.run rather than a bare os.popen.

Or, better yet, don't use a subprocess for simple file operations! Just do them in native Python code, and it will be much simpler.

Upvotes: 1

Related Questions