繁体   English   中英

命令替换与进程替换

[英]Command substitution vs process substitution

我试图理解这两个相似命令之间的差异。

aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
  • 我知道<()需要#!/bin/bash ,但这会让它变慢吗?
  • 他们创造了相同数量的子壳吗?
  • 他们需要相同数量的bashsh进程吗?

我希望使用具有最佳性能的命令。

  1. 不,Bash在非POSIX模式下更快。
  2. 这取决于。 这是特定于实现和特定于平台的细节。
    • 在Bash中,两者都需要相同数量的进程。 如果未启用lastpipe ,则每个管道元素都有一个进程加上替换加上父进程的子shell。
    • 在Bash中,如果启用了lastpipe ,则管道的最后一个元素将在两种情况下都不exec ,仍然需要相同数量的进程。
    • 在ksh93中,在这种情况下,两者都应该需要相同数量的进程,但如果最后一个管道元素是内置的,它将在父进程中运行以进行命令替换,从而使其更快。
    • 在Bash和ksh93中,如果shell是在不支持/dev/fd/*的系统上编译的,那么shell将为进程替换创建命名管道。 这可能会影响性能。
  3. 以前的子弹也许应该在这里。 注意“subshel​​l”并不一定意味着一个单独的进程,尽管在几乎所有的shell中都是如此(除了支持它的Bash之外的所有内容中的$(<...)除外)。 在mksh和ksh93中,还有${ ;}样式命令替换,但每个shell都以不同方式实现。 在ksh93中,它可能会也可能不会加速。 在mksh,可能不是。 mksh不支持进程替换,并且zsh不支持(并且无法模拟) BASHPID ,所以我没有调查过它。

命令替换本质上没有什么比Bash中的进程替换更快,但是在read的情况下head是多余的,因为你只在那里读取一行。 顺便说一句,总是使用head -n ... - -1不可移植。 另外,除非你想让shell破坏输入,否则不要使用不带-r read

提高性能的最佳方法是尽可能多地摆脱叉子和管道。

出于所有意图和目的,您不应该担心所述的性能问题。 99%的执行时间可能由特定命令决定,而不是由进程替换与命令替换的差异决定。 你知道优化的第一定律吗? 别。 特别是如果你牺牲了便携性。 使用$(whatever)并忘记其他一切。 如果你真的担心性能,那么你需要解决的是命令/管道/分支。 否则你会试图通过挤压眼泪来减肥。

使用Bash's内置time基准测试,第一种形式比第二种形式慢。

您可以使用以下方法自行测试:

bash -c 'time PIPELINE...'

两者都创建子壳 - 在第一种情况下使用shell读取并扩展壳的输出,并且在第二种情况下从shell read内置读取。

看到:

进程替换绕过由piplines /命令替换创建的子shell。 替换语法由FIFO或FD的名称替换,其中的命令在后台运行。 替换在参数扩展和命令替换的同时执行。

查看与“tee”一起使用的过程替换信息。

http://mywiki.wooledge.org/ProcessSubstitution

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM