在包装 bash 脚本中设置管道

Setup pipes inside wrapping bash script

假设我有一个 python 程序,我将其调用为

python main.py

我想将此程序包装到一个名为 execute 的 shell 脚本中,该脚本可能会事先进行一些设置

#!/bin/bash

# Do something interesting
python main.py

现在假设我想使用管道

./execute < inputData.txt > outputData.txt

我应该如何将这些管道(或 | 管道)重定向到我的 python 脚本?

类似于下面的东西,但更通用(我不知道我的输入和输出文件的名称,或者根本不知道是否有管道,也许我只是想要 stdin/stdout)

python main.py < inputData.txt > outputData.txt

一个快速的 hack 是让我的 python 可执行文件和 运行 而不是将其包装在 shell 脚本中,但我对学习管道更感兴趣。

在这种特殊情况下,您不必在 shell 脚本中指定管道或重定向。管道和重定向更改标准输入、输出和错误句柄。除非另有说明,否则这些句柄由子进程继承。因此,当您 运行 execute < input.txt 时,execute 和它执行的 python 的标准输入句柄将连接到 input.txt。如果您想更改 execute 的调用者设置的内容,您只需要在 execute 内指定重定向或管道。

术语注释:<>>>redirection 运算符,而不是管道。只有 | 是管道。机制相似,但管道需要 shell 来执行新进程。

编辑 我不知道有什么方法可以让脚本获取与其 stdin/stdout/stderr 句柄关联的文件名。在管道的情况下,没有这样的文件名!

另外,bash 有一个 process substitution 功能,有点像管道和重定向的混合。 execute < <(echo yes) 将 运行 echo yes,并将其输出放在一个特殊的文件名中(例如,/dev/fd/42)。特殊文件名出现在命令行上。所以结果就像 echo yes > /dev/fd/42 ; execute < /dev/fd/42。当您不想创建一个新的子 shell 时,这很有用,而 | 通常会这样做。