Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read Python stdin from pipe, without blocking on empty input

I am trying to read stdin in a Python script, while receiving from pipe.

I used these lines:

for line in sys.stdin:
    print line

And run the script: echo "test" | script.py

So far it works fine. However if I don't use a pipe the program sticks at the for command. Meaning that calling: ./script.py will make the script not work. How can I fix this?

like image 657
Ohad Avatar asked Nov 29 '18 14:11

Ohad


2 Answers

Edit: you apparently don't even want it to read lines in this case or handle KeyboardInterrupt, so what you need to do is check for empty stdin. Check if you are a terminal and pass as shown in the edited example.


sys.stdin is file-like. Try:

if not sys.stdin.isatty():
    data = sys.stdin.readlines()
    # Do something with data

If you run this with no stdin I don't think it will hang like it did for you before... because sys.stdin will be empty. The function should then continue.

like image 153
Charles Landau Avatar answered Oct 19 '22 07:10

Charles Landau


You can check if the program has been piped by calling isatty on the file descriptor derived from sys.stdin.

Like so :

import os
import sys

if not os.isatty(sys.stdin.fileno()):
    print (sys.stdin.readlines())
else:
    print ("Skip, so it doesn't hang")

Example 1 :

 echo "test" | python ./script.py
 ['test\n']

Example 2 :

 python ./script.py 
 Skip, so it doesn't hang
like image 1
Tezirg Avatar answered Oct 19 '22 06:10

Tezirg