子shell和进程替换之间的区别

子shell和进程替换之间的区别

在 bash 中,我想将当前工作目录分配给一个变量。使用子 shell,我可以做到这一点。

var=$(pwd)

echo $var
/home/user.name

如果我像这样使用进程替换:

var=<(pwd)

echo $var
/dev/fd/63

据我了解,进程替换主要在程序不接受 STDIN 时使用。我不清楚进程替换到底做什么以及为什么它分配/dev/fd/63var.

答案1

命令替换 ( $(...)) 将被替换为输出命令的,而进程替换 ( <(...)) 将被替换为一个文件名可以从中读取命令的输出。在这两种情况下,该命令都将在子 shell 中运行。

pwd就您而言, in的输出<(pwd)可能位于/dev/fd/63。一旦执行该命令,该文件将不再存在用途var进程替换已完成执行(当示例中的分配完成时)。

进程替换返回的文件名是文件描述符或命名管道的名称,而不是常规文件:

/dev/fd支持命名管道 (FIFO) 或命名打开文件的方法的系统支持进程替换。

进程替换的常见用途是为join命令预先排序文件:

$ join <( sort file1 ) <( sort file2 )

cut或者从文件中删除列(此处,通过使用两次并将paste结果拼接在一起,从制表符分隔的文件中删除第 2 列):

$ paste <( cut -f 1 file ) <( cut -f 3- file )

进程替换或多或少是避免显式使用临时文件的语法快捷方式。


命令替换和进程替换都是在子 shell 中执行的。如下所示,这些子 shell 中的环境不会影响父 shell 的环境:

$ unset t
$ echo "$( t=1234; echo "$t" )"
1234
$ echo "$t"
(empty line output)

在这里,从命令替换中echo获取1234字符串参数。

$ unset t
$ cat <( t=4321; echo "$t" )
4321
$ echo "$t"
(empty line output)

在这里,cat获取文件的文件名(命名管道/文件描述符)作为其参数。该文件包含数据4321

相关内容