使用系统参数从标准输入读取



我正在尝试将CSV文件分类到stdout中,然后将打印的输出作为输入输入到python程序中,该程序还采用具有1个参数的系统参数向量。我遇到了一个问题,我认为与 Python 的 fileinput.input(( 函数在占用 stdin 文件描述符方面的反应直接相关。

generic_user% cat my_data.csv | python3 my_script.py myarg1

下面是一个示例 Python 程序:

import sys, fileinput
def main(argv):
print("The program doesn't even print this")
data_list = []
for line in fileinput.input():
data_list.append(line)
if __name__ == "__main__":
main(sys.argv)

如果我尝试使用上述终端命令运行此示例程序并且没有参数 myarg1,该程序能够评估和解析 stdin 以获取 CSV 文件的数据输出。

如果我使用参数 myarg1运行程序,它最终会抛出与不作为文件存在的 myarg1 直接相关的 FileNotFoundError。

FileNotFoundError: [Errno 2] No such file or directory: 'myarg1'

有人能够详细解释为什么这种行为发生在 Python 中以及如何处理逻辑,以便 Python 程序可以在 argv 覆盖 stdin 描述符之前首先处理 stdin 数据?

您可以直接从stdin中读取:

import sys
def main(argv):
print("The program doesn't even print this")
data_list = []
for line in iter(sys.stdin):
data_list.append(line)
if __name__ == "__main__":
main(sys.argv)

您正在尝试访问尚未创建的文件,因此fileinput无法打开它,但是由于您正在管道传输数据,因此不需要它。

这是设计使然fileinput的概念家认为,在某些情况下,从 stdin 读取是无稽之谈,只是提供了一种专门将stdin添加到文件列表中的方法。根据参考文档:

import fileinput
for line in fileinput.input():
process(line)

这将遍历 sys.argv[1:] 中列出的所有文件的行,如果列表为空,则默认为 sys.stdin。如果文件名为"-",则也会替换为 sys.stdin

只需保留您的代码并使用:generic_user% cat my_data.csv | python3 my_script.py - myarg1

在文件之前读取 stdinmyarg1或者如果您想在文件之后读取 stdin:... python3 my_script.py myarg1 -

fileinput实现了Unix实用程序通用的模式:

  • 如果使用命令行参数调用该实用程序,则它们是要从中读取的文件。
  • 如果调用它时没有参数,则从标准输入读取。

因此,fileinput完全按照预期工作。目前尚不清楚您使用命令行参数的目的,但是如果您不想停止使用fileinput,则应在调用之前修改sys.argv

some_keyword = sys.argv[1]
sys.argv = sys.argv[:1]      # Retain only argument 0, the command name
for line in fileinput.input():
...

最新更新