5

sys.stdin.readline()返回之前等待 EOF(或新行),所以如果我有控制台输入,则readline()等待用户输入。相反,如果没有要处理的内容,我想打印帮助并以错误退出,而不是等待用户输入。

原因:我正在寻找一个命令行行为类似于grep.

测试用例:

没有输入,也没有任何管道,打印帮助

$ argparse.py
argparse.py - prints arguments

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

命令行参数解析

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

接受管道命令

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

parseargs.py 清单:

# $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)
4

3 回答 3

5

grep可以按照它的方式工作,因为它有一个非可选参数:模式。例如

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

即使标准输入上有无限的输入,grep 也没有得到所需的参数,因此抱怨。

如果您只想使用可选参数并在 stdin 是终端时出错,请查看file.isatty()

于 2012-10-30T16:21:46.227 回答
4
import sys,os
print os.fstat(sys.stdin.fileno()).st_size > 0

调用脚本

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

c:\py_exp>peek_stdin.py
False
于 2012-10-30T16:27:10.120 回答
0

您可能需要检查getopt模块。基本示例:

import getopt
import sys

def main(argv):
    try:
        opts, args = getopt.getopt(argv, "has:f:") # "has:f:" are the arguments 
    except getopt.GetoptError:
        print "print usage()"
        sys.exit(1)
    if not opts and not args:
        print "print usage()"
        sys.exit(1)

    print "args passed", opts, args
if __name__ == "__main__":
    main(sys.argv[1:])


~> python blabla.py
print usage()
~> python blabla.py -a arg
args passed [('-a', '')] ['arg']
~> python blabla.py -b as  ----> this fails because -b is not defined for getopt at second parameter
print usage()

这个如何:

#!/usr/bin/env python
import getopt
import sys
import select


def main(argv):
    try:
        opts, args = getopt.getopt(argv, "has:f:") # "has:f:" are the arguments
    except getopt.GetoptError:
        print "print usage()"
        sys.exit(1)
    if not opts and not args:
        a, b, c = select.select([sys.stdin], [], [], 0.2)
        if a:
            itera = iter(a[0].readline, "")
            for line in itera:
                data = line.strip()
                print data
        else:
            print "print usage()"

    print "args passed", opts, args
if __name__ == "__main__":
    main(sys.argv[1:])

select.select 有助于检查是否有数据到来

:~> ./hebele.py 
print usage()
args passed [] []

:~> ping www.google.com | ./hebele.py 
PING www.google.com (173.194.67.105) 56(84) bytes of data.
64 bytes from blabla (173.194.67.105): icmp_seq=1 ttl=48 time=16.7 ms
64 bytes from blabla (173.194.67.105): icmp_seq=2 ttl=48 time=17.1 ms
64 bytes from blabla (173.194.67.105): icmp_seq=3 ttl=48 time=17.1 ms
^CTraceback (most recent call last):
  File "./hebele.py", line 25, in <module>
    main(sys.argv[1:])
  File "./hebele.py", line 17, in main
    for line in itera:
KeyboardInterrupt
:~> ls | ./hebele.py 
Aptana_Studio_3
Desktop
...
workspace
args passed [] []

:~> ./hebele.py -a bla
args passed [('-a', '')] ['bla']
:~> ./hebele.py sdfsdf sadf sdf
args passed [] ['sdfsdf', 'sadf', 'sdf']
于 2012-10-30T16:48:37.213 回答