例如:
script1.py从用户获取中缀表达式并将其转换为后缀表达式并将其返回或将其打印到stdout
script2.py从stdin获取一个后缀表达式并对其进行求值并输出值
我想做这样的事情:
python3 script1.py | python3 script2.py
这不起作用,你能指出我如何做到这一点的正确方向吗?
编辑 -
这里有一些关于什么"没有工作的更多细节"。
当我执行 python3 script1.py |时python3 script2.py 终端要求我输入script2.py程序,当它应该要求输入script1.py程序并将其重定向为script2.py的输入时。
所以它要求我"输入一个后缀表达式:",当它应该询问"输入中缀表达式时:"并将其重定向到后缀脚本。
答案 0 :(得分:1)
如果我没有正确地解决您的问题,那么您的两个脚本都会写出输入提示。例如,它们都可能是这样的:
in_string = input("Enter something")
print(some_function(in_string))
其中some_function
是一个具有不同输出的函数,具体取决于输入字符串(在每个脚本中可能不同)。
问题是,当一个脚本的输出通过管道传输到另一个脚本时,"Enter something"
提示不会正确显示给用户。这是因为提示符被写入标准输出,因此第一个脚本的提示符被传送到第二个脚本,同时显示第二个脚本的提示符。这是误导性的,因为它是(直接)接收用户输入的第一个脚本。提示文本也可能搞乱两个脚本之间传递的数据。
这个问题没有完美的解决方案。一个部分解决方案是将提示写入标准错误,而不是标准输出。这可以让你看到两个提示(虽然你实际上只能响应其中一个提示)。我不认为您可以使用input
直接执行此操作,但print
可以根据需要写入其他文件流:print("prompt", file=sys.stderr)
另一个部分解决方案是检查您的输入和输出是否流,并跳过提示,如果其中任何一个不是" tty" (终奌站)。在Python中,您可以sys.stdin.isatty()
。许多命令行程序都有不同的交互模式"如果他们直接连接到用户,而不是管道或文件。
如果管道输出是程序的主要功能,您可能不想使用提示!许多标准的Unix命令行程序(如cat
和grep
)根本没有任何交互行为。它们要求用户传递命令行参数或设置环境变量以控制它们的运行方式。即使他们无法访问标准输入和标准输出,这也可以让他们按预期工作。
答案 1 :(得分:0)
例如,如果你有运行nginx和script1.py:
import os
os.system("ps aux")
和script2.py
import os
os.system("grep nginx")
然后跑步:
python script1.py | script2.py
与
相同ps aux | grep nginx
答案 2 :(得分:0)
为了完成起见,并提供使用os
模块的替代方法:
fileinput
模块为您处理管道,并且通过运行简单的测试,我相信它将使其变得简单。
要启用文件以支持管道输入,只需执行以下操作:
import fileinput
with fileinput.input() as f_input: # This gets the piped data for you
for line in f_input:
# do stuff with line of piped data
然后你要做的就是:
$ some_textfile.txt | ./myscript.py
请注意,fileinput还为您的脚本启用数据输入,如下所示: $ ./myscript.py some_textfile.txt $ ./myscript.py< some_textfile.txt
这与python的打印输出一样容易:
>test.py # This prints the contents of some_textfile.txt
with open('some_textfile.txt', 'r') as f:
for line in f:
print(line)
$ ./test.py | ./myscript.py
当然,不要忘记脚本顶部的hashbang #!/usr/bin/env python
以便这种方式工作。
配方在Beazley & Jones's Python Cookbook中有所体现 - 我全心全意地推荐它。