命令替换VS进程替换(Command substitution vs process substit

2019-07-21 15:39发布

我想了解这两种类似的命令之间的差异。

aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
  • 我知道, <()要求#!/bin/bash ,但使得它更慢?
  • 难道他们创建子shell中的一样多吗?
  • 他们是否需要相同数量bashsh进程?

我期待使用命令具有最佳性能。

Answer 1:

  1. 第Bash是在非POSIX模式快。
  2. 这取决于。 这既是实现特定的,特定于平台的细节。
    • 在bash中,都需要相同数量的进程。 如果lastpipe未启用,则每个管道元素加上无论是替代加父进程子shell进程。
    • 在bash,如果lastpipe启用,管道的最后一个元素将exec不分叉在这两种情况下,仍然需要相同数量的进程。
    • 在ksh93的,都应该要求相同数量的在这种情况下的过程,但如果最后的管道元素是一个内置的,它会在父的命令替换的过程中运行,使之更快。
    • 在这两个Bash和ksh93的,如果外壳被编译在不支持的系统上/dev/fd/* ,外壳将创建命名管道的过程,而不是替代。 这可能会影响性能。
  3. 以前的子弹或许应该去这里。 注意“亚层”并不一定意味着一个单独的进程,但在几乎所有的炮弹,但它确实(有例外$(<...)的一切,除了猛砸支持它)。 在mksh和ksh93的,另外还有${ ;}风格命令替换,但每个不同的壳实现这一点。 在ksh93的,它可能会或可能不会给出一个加速。 在mksh,大概不会。 mksh不支持进程替换和zsh中不支持(并没有办法模拟的) BASHPID ,所以我还没有看进去。

没有什么本质上快约比猛砸一个进程替换命令替换,但head是在的情况下,多余的read ,因为你只读取一行那里。 顺便说一句,总是用head -n ... - -1是不可移植。 另外,不要使用read没有-r ,除非你希望shell裂伤输入。



Answer 2:

在这里提高性能的最佳方式是让尽可能多的,你可以摆脱叉子和管道。

对于所有意图和目的,说明你不应该担心性能问题。 的执行时间99%是可能由特定的命令,而不是在处理取代对命令取代的差值来确定。 你知道最优化的第一定律? 别。 特别是如果你牺牲便携性。 使用$(whatever) ,忘记了一切。 如果你确实担心性能,你需要解决的命令/管/叉。 否则,你想从你的眼睛挤眼泪减肥。



Answer 3:

标杆Bash's内置time ,第一种形式比第二慢。

你可以自己与测试:

bash -c 'time PIPELINE...'

这两种创建子shell -与外壳的阅读和扩大一个子shell在第一种情况下的输出,与外壳的read内置在第二后台进程读取。

看到:

  • http://mywiki.wooledge.org/ProcessSubstitution
  • http://mywiki.wooledge.org/BashFAQ/002
  • http://mywiki.wooledge.org/BashFAQ/082


Answer 4:

进程替换绕过由piplines /命令替换创建子shell。 该替换语法由FIFO或FD的名称代替,并且在其内部的指令是在后台运行。 的取代是在同一时间作为参数扩展和命令替换进行

看看与使用过程代替信息“三通”为好。

http://mywiki.wooledge.org/ProcessSubstitution



文章来源: Command substitution vs process substitution