【问题标题】:The "> (tee -a ...)" command in BashBash 中的 "> (tee -a ...)" 命令
【发布时间】:2015-03-11 16:27:11
【问题描述】:

我有这个运行 Scala 测试代码的 Bash 代码:

scripts=(
Hello.scala
)

for script in "${scripts[@]}"; do
    echo scala "${script}"
    scala -nocompdaemon "${script}" > >(tee -a _testoutput.txt) \
        2> >(tee -a _testerrors.txt >&2)
done

如何解释>(tee -a _testoutput.txt)?我通常使用|(管道)来使用tee。使用这个表达式有什么区别?

【问题讨论】:

    标签: bash unix tee


    【解决方案1】:

    在这种情况下,我相信 > >(tee -a _testoutput.txt)| tee -a _testoutput.txt 的行为会相同。

    standard error 版本显然是必要的,因为没有标准错误管道。

    管道版本和 process substitution (>(...)) 版本之间的另一个主要区别是子外壳发生的位置。

    例如,如果>(...) 在整个循环中,并且您需要在循环中设置变量以在循环之外持续存在,那么您无法使用管道版本执行此操作(有关此内容的更多信息,请参阅Bash FAQ 24 )。

    另一个区别,正确的pointed out by Charles Duffy,是管道会影响管道的退出状态(默认情况下,尽管set -o pipefail 改变了这一点,而 Bash PIPESTATUS数组保存所有退出状态)。另一方面,进程替换不会影响退出状态。

    【讨论】:

    • 另一个区别是退出状态; > >(tee -a foo) 不会改变退出状态,而| tee -a foo 会。
    • 使用进程替换可能有一些注意事项:如果被替换的进程提前结束并且主进程仍想写一些东西,那么它将接收 SIGPIPE:{ sleep 1; echo a; } > >(:) 的主进程。跨度>
    【解决方案2】:

    >( list ) 被称为“进程替换”。它比普通管道更强大:您不能使用| 将标准输出和标准错误如此轻松地重定向到不同的程序。

    【讨论】:

    • 可以使用管道将标准输出和标准错误重定向到不同的程序,使用适当的重定向。这有点难看,但没有任何重大警告是可行的。
    • @gniourf_gniourf:没错,用2>&7 之类的,你可以。已更新。
    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多