如果在Python中没有管道传输,如何从标准输入或文件中读取?

问题描述 投票:17回答:6

我有一个CLI脚本,希望它从文件中读取数据。它应该能够以两种方式阅读它:

  • cat data.txt | ./my_script.py
  • ./my_script.py data.txt

-例如有点像grep

我知道:

  • [sys.argvoptparse让我轻松阅读任何参数和选项。
  • sys.stdin让我读取通过管道传输的数据
  • fileinput使整个过程自动化

不幸的是:

  • 使用fileinput使用stdin和所有args作为输入。因此,在尝试打开非文件名的选项时,我将无法使用它们。
  • sys.stdin.readlines()可以正常工作,但是如果我不传送任何数据,它将挂起,直到我输入Ctrl + D
  • 我不知道如何实现“如果在stdin中什么都没有,请从args中的文件中读取”,因为stdin在布尔上下文中始终为True

如果可能,我想采用一种便携式的方式来执行此操作。

python pipe stdin command-line-interface
6个回答
11
投票

根据您的需要处理非文件名参数,因此最终得到一个非选项参数数组,然后将该数组作为参数传递给fileinput.input()

fileinput.input()

20
投票

[import fileinput for line in fileinput.input(remaining_args): process(line) 允许以相当简单的方式完成此操作,除非有兼容性问题,否则您确实应该使用它而不是Argparse

代码将如下所示:

optparse

现在您有一个解析器,它将解析您的命令行参数,如果看到一个,则使用一个文件,如果没有,则使用标准输入。


9
投票

对于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来说,并非一无所获


4
投票

我是菜鸟,所以这可能不是一个好的答案,但是我正在尝试做同样的事情(允许在命令行上一个或多个文件,否则默认为STDIN)。


3
投票

[没有可靠的方法来检测cat --file file1 --file file2 是否连接到任何东西,也不适合这样做(例如,用户要粘贴数据)。检测文件名是否存在作为参数,如果找不到则使用stdin。


2
投票

您可以使用此功能来检测输入是否来自管道。

© www.soinside.com 2019 - 2024. All rights reserved.