我有一个CLI脚本,希望它从文件中读取数据。它应该能够以两种方式阅读它:
cat data.txt | ./my_script.py
./my_script.py data.txt
-例如有点像grep
。
我知道:
sys.argv
和optparse
让我轻松阅读任何参数和选项。sys.stdin
让我读取通过管道传输的数据fileinput
使整个过程自动化不幸的是:
fileinput
使用stdin和所有args作为输入。因此,在尝试打开非文件名的选项时,我将无法使用它们。sys.stdin.readlines()
可以正常工作,但是如果我不传送任何数据,它将挂起,直到我输入Ctrl + Dstdin
在布尔上下文中始终为True
。如果可能,我想采用一种便携式的方式来执行此操作。
根据您的需要处理非文件名参数,因此最终得到一个非选项参数数组,然后将该数组作为参数传递给fileinput.input()
:
fileinput.input()
[import fileinput
for line in fileinput.input(remaining_args):
process(line)
允许以相当简单的方式完成此操作,除非有兼容性问题,否则您确实应该使用它而不是Argparse。
代码将如下所示:
optparse
现在您有一个解析器,它将解析您的命令行参数,如果看到一个,则使用一个文件,如果没有,则使用标准输入。
对于Unix / Linux,您可以通过查看import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--input', type = argparse.FileType('r'), default = '-')
来检测是否正在通过管道传输数据
os.isatty(0)
我不确定Windows是否有等效的版本。
编辑好的,我在Windows XP上用python2.6尝试过]
$ date | python -c "import os;print os.isatty(0)" False $ python -c "import os;print os.isatty(0)" True
因此,对于Windows来说,并非一无所获
我是菜鸟,所以这可能不是一个好的答案,但是我正在尝试做同样的事情(允许在命令行上一个或多个文件,否则默认为STDIN)。
[没有可靠的方法来检测cat --file file1 --file file2
是否连接到任何东西,也不适合这样做(例如,用户要粘贴数据)。检测文件名是否存在作为参数,如果找不到则使用stdin。
您可以使用此功能来检测输入是否来自管道。