bash 如何将一个 python 脚本的输出作为输入传递给另一个 python 脚本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37847232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:46:49  来源:igfitidea点击:

How do I pipe output from one python script as input to another python script?

bashshellpython-3.xpipeio-redirection

提问by 7alman

For example:

例如:

A script1.py gets an infix expression from the user and converts it to a postfix expression and returns it or prints it to stdout

script1.py 从用户那里获取一个中缀表达式并将其转换为后缀表达式并返回或打印到标准输出

script2.py gets a postfix expression from stdin and evaluates it and outputs the value

script2.py 从 stdin 获取后缀表达式并对其求值并输出值

I wanted to do something like this:

我想做这样的事情:

python3 script1.py | python3 script2.py

This doesn't work though, could you point me in the right direction as to how I could do this?

但这不起作用,你能指出我如何做到这一点的正确方向吗?

EDIT -

编辑 -

here are some more details as to what "doesn't work".

这里有一些关于“不起作用”的更多细节。

When I execute python3 script1.py | python3 script2.pythe terminal asks me for input for the script2.py program, when it should be asking for input for the script1.py program and redirecting that as script2.py's input.

当我执行python3 script1.py | python3 script2.py终端要求我输入 script2.py 程序,当它应该要求输入 script1.py 程序并将其重定向为 script2.py 的输入时。

So it asks me to "Enter a postfix expression: ", when it should be asking "Enter an infix expression: " and redirect that to the postfix script.

所以它要求我“输入后缀表达式:”,当它应该询问“输入中缀表达式:”并将其重定向到后缀脚本时。

采纳答案by Blckknght

If I undestand your issue correctly, your two scripts each write out a prompt for input. For instance, they could both be something like this:

如果我正确理解您的问题,您的两个脚本都会写出一个输入提示。例如,它们都可能是这样的:

in_string = input("Enter something")
print(some_function(in_string))

Where some_functionis a function that has different output depending on the input string (which may be different in each script).

some_function根据输入字符串(每个脚本中可能不同)具有不同输出的函数在哪里。

The issue is that the "Enter something"prompt doesn't get displayed to the user correctly when the output of one script is being piped to another script. That's because the prompt is written to standard output, so the first script's prompt is piped to the second script, while the second script's prompt is displayed. That's misleading, since it's the first script that will (directly) receive input from the user. The prompt text may also mess up the data being passed between the two scripts.

问题是"Enter something"当一个脚本的输出通过管道传输到另一个脚本时,提示没有正确显示给用户。这是因为提示被写入标准输出,所以第一个脚本的提示通过管道传送到第二个脚本,而第二个脚本的提示被显示。这是一种误导,因为它是第一个(直接)接收用户输入的脚本。提示文本也可能会混淆两个脚本之间传递的数据。

There's no perfect solution to this issue. One partial solution is to write the prompt to standard error, rather than standard output. This would let you see both prompts (though you'd only actually be able to respond to one of them). I don't think you can directly do that with input, but printcan write to other file streams if you want: print("prompt", file=sys.stderr)

这个问题没有完美的解决方案。一种部分解决方案是将提示写入标准错误,而不是标准输出。这将使您看到两个提示(尽管您实际上只能响应其中之一)。我认为您不能直接使用input,但print可以根据需要写入其他文件流:print("prompt", file=sys.stderr)

Another partial solution is to check if your input and output streams and skip printing the prompts if either one is not a "tty" (terminal). In Python, you can do sys.stdin.isatty(). Many command line programs have a different "interactive mode" if they're connected directly to the user, rather than to a pipe or a file.

另一个部分解决方案是检查您的输入和输出流是否并跳过打印提示,如果其中任何一个不是“tty”(终端)。在 Python 中,您可以执行sys.stdin.isatty(). 如果许多命令行程序直接连接到用户,而不是连接到管道或文件,则它们具有不同的“交互模式”。

If piping the output around is a main feature of your program, you may not want to use prompts ever! Many standard Unix command-line programs (like catand grep) don't have any interactive behavior at all. They require the user to pass command line arguments or set environment variables to control how they run. That lets them work as expected even when they don't have access to standard input and standard output.

如果管道输出是您程序的主要功能,您可能永远不想使用提示!许多标准的 Unix 命令行程序(如catgrep)根本没有任何交互行为。它们要求用户传递命令行参数或设置环境变量来控制它们的运行方式。这让他们即使在无法访问标准输入和标准输出时也能按预期工作。

回答by nlsdfnbch

For completion's sake, and to offer an alternative to using the osmodule:

为了完成,并提供使用os模块的替代方法:

The fileinputmodule takes care of piping for you, and from running a simple test I believe it'll make it an easy implementation.

fileinput模块为您处理管道,通过运行一个简单的测试,我相信它会使其成为一个简单的实现。

To enable your files to support piped input, simply do this:

要使您的文件支持管道输入,只需执行以下操作:

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

all you'd have to do then is:

你所要做的就是:

$ some_textfile.txt | ./myscript.py

Note that fileinput also enables data input for your scripts like so: $ ./myscript.py some_textfile.txt $ ./myscript.py < some_textfile.txt

请注意, fileinput 还为您的脚本启用数据输入,如下所示: $ ./myscript.py some_textfile.txt $ ./myscript.py < some_textfile.txt

This works with python's print output just as easily:

这同样适用于 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

Of course, don't forget the hashbang #!/usr/bin/env pythonat the top of your scripts for this way to work.

当然,不要忘记#!/usr/bin/env python脚本顶部的 hashbang以便以这种方式工作。

The recipe is featured in Beazley & Jones's Python Cookbook- I wholeheartedly recommend it.

该食谱在Beazley & Jones 的 Python Cookbook 中有特色- 我全心全意地推荐它。

回答by dmitryro

For example if you have nginx running and script1.py:

例如,如果你有 nginx 运行和 script1.py:

import os

os.system("ps aux")

and script2.py

和 script2.py

import os

os.system("grep nginx")

Then running:

然后运行:

python script1.py | script2.py

will be same as

将与

ps aux | grep nginx