【问题标题】:Setup pipes inside wrapping bash script在包装 bash 脚本中设置管道
【发布时间】:2018-03-24 13:35:41
【问题描述】:

假设我有一个我调用的 python 程序

python main.py

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

#!/bin/bash

# Do something interesting
python main.py

现在假设我想使用管道

./execute < inputData.txt > outputData.txt

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

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

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

一个快速的技巧是让我的 python 可执行并运行它,而不是将它包装在一个 shell 脚本中,但我对学习管道更感兴趣。

【问题讨论】:

    标签: bash shell redirect pipe child-process


    【解决方案1】:

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

    关于术语的注意事项:&lt;&gt;&gt;&gt;redirection 运算符,而不是管道。只有| 是一个管道。机制类似,但管道需要 shell 来执行新进程。

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

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

    【讨论】:

    • 谢谢!感谢支持者将我推到 10k 代表! :D :D
    • 非常感谢!那肯定有帮助。事后看来,我的问题很愚蠢,这就是为什么我没有发现它在 SO 上被问到的原因。感谢您的澄清。
    • @AndreiCioara 没有愚蠢的问题:)。实际上,像“你不需要做任何特别的事情”这样的答案通常很难找到,因为文档通常会告诉你默认行为,而没有解释它如何适用于不同的情况。快乐的黑客攻击!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2018-05-07
    相关资源
    最近更新 更多