根据维基百科的说法,“进程替换也可用于捕获通常发送到文件的输出,并将其重定向到进程的输入。”(http://en.wikipedia.org/wiki/Process_substitution)。
所以,用我自己的话说,这意味着通过进程替换,我可以获取命令A的输出并将其用作命令B的输入。换句话说,它就像一个管道(这是正确的吗?)
如果这是真的,如果我这样做:
echo "test" >(wc)
然后我应该得到以下结果:
1 1 5
因为我对上述命令的理解类似于以下内容:
$echo "test" > tmp
$wc tmp
1 1 5 tmp
除了我没有使用进程替换生成tmp文件。
但我得到以下输出:
test /dev/fd/63
这显然表明我的心理模型不正确。我哪里错了?
我理解<(命令)。例如
$diff <(head file1) <(head file2)
完全有道理。但不是&gt;(命令)。
答案 0 :(得分:3)
进程列表运行时其输入或输出连接到 FIFO或 / dev / fd 中的某个文件。 作为扩展的结果,此文件的名称作为参数传递给当前命令。如果使用&gt;(列表)表单,写入文件将为列表提供输入。
echo "test" >(wc)
会怎样?
文件/dev/fd/63
已打开,可将echo test
与wc
联系起来。 wc
启动时,其输入已连接到/dev/fd/63
。然后将此文件的名称(/dev/fd/63
)作为参数传递给当前命令(echo "test"
),从而生成echo "test" /dev/fd/63
。这就是你看到
test /dev/fd/63
作为输出。 wc
等待输入,但由于echo
未写入/dev/fd/63
,因此计数将为0
。
如果你希望这个工作,你必须创建一个脚本,它接受最后一个参数并将第一个N-1
参数回显到最后一个
#! /bin/bash
echo "${@:1:$(($# - 1))}" >${@: -1}
当你打电话给这个
bash script.sh test >(wc)
您将看到预期的输出
1 1 5
答案 1 :(得分:2)
您的心理模型不正确,因为您错过了一个重要细节:流程替换不是重定向。
执行重定向时,例如&#34; echo test&gt; tmp&#34;,执行的是&#34; echo test&#34;,并且stdout(由&#34;&gt;&#34;表示)被定向到名为&#34; tmp&的文件中#34 ;.当您执行替换时,例如&#34; echo test&gt;(wc)&#34;,&#34; wc&#34;执行,&#34;&gt;(wc)&#34;被可以读取或写入的文件名(或可能是魔法设备的名称)取代。
引自您链接到的维基百科页面:&#34;在引擎盖下,进程替换通过创建命名管道,然后在命令行上替换其名称来工作。&#34;
如果仔细观察&#34;差异&#34;上面的示例,您也会看到它,它的工作方式相同。毕竟,&#34; diff&#34;的论点是什么?但命令行上的文件名?