Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I avoid processing an empty stdin with python?

Tags:

python

stdin

The sys.stdin.readline() waits for an EOF (or new line) before returning, so if I have a console input, readline() waits for user input. Instead I want to print help and exit with an error if there is nothing to process, not wait for user input.

Reason: I'm looking to write a python program with command line behaviour similar to grep.

Test cases:

No input and nothing piped, print help

$ argparse.py
argparse.py - prints arguments

echo $?            # UNIX
echo %ERRORLEVEL%  # WINDOWS
2

Command line args parsed

$ argparse.py a b c 
0 a
1 b
2 c

Accept piped commands

$ ls | argparse.py
0 argparse.py
1 aFile.txt

parseargs.py listing:

# $Id: parseargs.py

import sys
import argparse

# Tried these too:
# import fileinput - blocks on no input
# import subprocess - requires calling program to be known

def usage():
    sys.stderr.write("{} - prints arguments".fomrat(sys.argv[0])
    sys.stderr.flush()
    sys.exit(2)

def print_me(count, msg):
    print '{}: {:>18} {}'.format(count, msg.strip(), map(ord,msg))

if __name__ == '__main__':
    USE_BUFFERED_INPUT = False
    # Case 1: Command line arguments  
    if len(sys.argv) > 1:
        for i, arg in enumerate(sys.argv[1:]):
            print_me( i, arg)
    elif USE_BUFFERED_INPUT:  # Note: Do not use processing buffered inputs  
        for i, arg in enumerate(sys.stdin):
            print_me( i, arg)
    else:
        i=0
        #####  Need to deterime if the sys.stdin is empty.
        #####  if READLINE_EMPTY:
        #####      usage()
        while True:
            arg = sys.stdin.readline() #Blocks if no input
            if not arg:
                break
            print_me( i, arg)
            i += 1
    sys.exit(0)
like image 223
Bruce Peterson Avatar asked Oct 30 '12 16:10

Bruce Peterson


2 Answers

grep can work the way it does because it has one non-optional argument: the pattern. For example

$ grep < /dev/zero
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.

even though there was infinite input available on stdin, grep didn't get the required argument and therefore complained.

If you want to use only optional arguments and error out if stdin is a terminal, look at file.isatty().

like image 112
msw Avatar answered Oct 30 '22 15:10

msw


import sys,os
print os.fstat(sys.stdin.fileno()).st_size > 0

Calling script

c:\py_exp>peek_stdin.py < peek_stdin.py
True

c:\py_exp>peek_stdin.py
False
like image 35
Joran Beasley Avatar answered Oct 30 '22 13:10

Joran Beasley