强制Python脚本从标准输入获取输入

7

我需要运行一个Python脚本,该脚本只接受作为命令行参数传递的文件输入,例如:

$ markdown.py input_file

有没有办法让它接受标准输入而不是文件输入?我想通过Bash实现这一点,而不需要显著修改Python脚本:
$ echo "Some text here" | markdown.py

如果我需要修改Python脚本,我该怎么做?

(编辑:这里是解析命令行选项的脚本。)

6个回答

11

我不确定它的可移植性有多高,但在类Unix系统上,您可以将/dev/stdin作为您的文件名:

$ echo -n hi there | wc /dev/stdin
       0       2       8 /dev/stdin

4

请确保此内容位于文件顶部附近:

import sys

然后寻找类似于这样的内容:
filename = sys.argv[1]
f = open(filename)

并将其替换为这个:

f = sys.stdin

如果没有看到你要开始处理的脚本,很难提供更具体的信息。


这是文件的链接:http://codaset.com/repo/python-markdown/source/master/blob/067d88bc41c7924c9087b724ff5247235243ce6b/markdown/commandline.py。它使用optparse模块,因此没有sys.argv[]。 - Karthik

0
在代码中你有这样一行:
if not len(args) == 1:

你可以在那里做的是检查是否没有文件名,而是使用“/dev/stdin”(在允许的系统上)。

另一个解决方案是只需替换:

if not len(args) == 1:
    parser.print_help()
    return None, None
else:
    input_file = args[0]

使用

if not len(args) == 1:
    input_file = sys.stdin
else:
    input_file = open(args[0])

这意味着返回的“input_file”不再是文件名,而是文件对象,这意味着调用函数中需要进行进一步修改。

第一种解决方案需要进行较少的修改,但更具平台特定性;第二种解决方案需要更多的工作,但应该可以在更多的系统上运行。


0
我从你的问题细节猜测你在问有关 Python-Markdown 的问题,因此我为你找到了相关源代码中的那一行:如果按照 Daniel 的方法,在markdown/__init__.py的第443行,您需要替换...
input_file = codecs.open(input, mode="r", encoding=encoding)

使用

input_file = codecs.EncodedFile(sys.stdin, encoding)

虽然这样做之后您将无法实际处理文件,因此为了更普遍有用的技巧,您可以加入一个条件语句:

if input:
    input_file = codecs.open(input, mode="r", encoding=encoding)
else:
    input_file = codecs.EncodedFile(sys.stdin, encoding)

然后你需要调整markdown/commandline.py,以便在没有给定文件名时不退出:修改72-73行

parser.print_help()
return None, None

input_file = None

问题在于,这并不是一件简单的事情。此时我本来想建议使用像Mark Rushakoff那样的特殊文件,但他已经先我一步了;-)

0
在bash中,您还可以使用处理替换
markdown.py <(echo "Some text here")

对于单个输入,/dev/stdin 可以工作,但进程替换也适用于多个输入(甚至输出)


0

那个网站看起来有点死气沉沉,我认为去他们的Gitorious项目,在一个分支中实现变更,然后请求将其合并到项目中可能会更加有成果。 - David Z

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接