Find out if there is pipe input or not in Python?

(I think) I know how to read from a pipe. I mean bash calls like this

echo Bรคhm | ./script.py 

This Python3 script works with this.

 #!/usr/bin/env python3 import sys x = sys.stdin.read() if x: print(x) else: print('no pipe') sys.exit() 

But when I just do it on bash

 ./script.py 

nothing happens because it is waiting for input.

So, I want to check (when running the script) if there is input from the channel or not. But I do not know why size or len did not work on sys.stdin or sys.stdin.buffer .

Maybe there is a difference in processing between Python versions 2 and 3?

+7
python pipe
source share
4 answers

nothing happens because it is waiting for input

And this is completely normal. You want to fix something that does not require any corrections, and as a by-product that you are actually creating.

Imagine a pipeline process that does some heavy calculations, and because of this, it takes some time to output the result. You cannot check data availability in your python script. You do not know when the data will be available. You must be patient.

So, I want to check (when running the script) if there is input from the pipe or not.

not to do. If for some reason your application is not designed to run with tty (waiting for user input), check this out.

 sys.stdin.isatty() 

Check only the availability of data if there is some kind of strict restriction: for example, the user must respond within 2 seconds.

+3
source share

As an alternative to @Cyrbil, answer if you really need to know if the login has been entered into the system, you can use isatty :

 from sys import stdin from os import isatty is_pipe = not isatty(stdin.fileno()) 
+2
source share

You can set the input input file to non-blocking and catch IOError: [Errno 11] Resource temporarily unavailable when nothing is sent.

 import fcntl import os import sys # make stdin a non-blocking file fd = sys.stdin.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) try: print(sys.stdin.read()) except: print('No input') 
0
source share

You can use select, but it does not work on Windows:

 import sys import select # Input: zero or more file-like objects # Returns: list of objects that can be read def can_read_files(*args): return select.select(args, [], [], 0.0)[0] if can_read_files(sys.stdin): print(sys.stdin.read()) else: print('No input') 

For us, this is inline:

 if select.select([sys.stdin], [], [], 0.0)[0]: ... 
0
source share

All Articles