4

根据维基百科,“进程替换也可用于捕获通常会进入文件的输出,并将其重定向到进程的输入。”(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) 

完全有道理。但不是>(命令)。

4

2 回答 2

3

Process Substitution

进程列表在其输入或输出连接到FIFO 或/dev/fd中的某个文件时运行。作为扩展的结果,此文件的名称作为参数传递给当前命令。如果使用 >(list) 形式,写入文件将为 list 提供输入

会发生什么echo "test" >(wc)

打开该文件以/dev/fd/63用于连接。开始时它的输入连接到. 然后将该文件的名称 ( ) 作为参数传递给当前命令 ( ),从而生成. 这就是为什么你看到echo testwcwc/dev/fd/63/dev/fd/63echo "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
于 2013-04-17T22:40:41.813 回答
2

你的心智模型是不正确的,因为你错过了一个重要的细节:流程替换不是重定向。

当您执行“echo test > tmp”等重定向时,执行的是“echo test”,标准输出(由“>”表示)被定向到名为“tmp”的文件中。当您执行替换时,例如“echo test >(wc)”,“wc”被执行,“>(wc)”被替换为文件名(或者可能是魔法设备的名称)可以读取或写入。

正如您链接到的维基百科页面所引用的那样:“在后台,进程替换通过创建命名管道,然后在命令行上替换其名称来工作。”

如果您仔细查看上面的“差异”示例,您也会发现它的工作方式相同。毕竟,除了命令行上的文件名之外,“diff”的参数是什么?

于 2013-04-17T22:40:59.003 回答