在 bash 中,我想将当前工作目录分配给一个变量。使用子 shell,我可以做到这一点。
var=$(pwd)
echo $var
/home/user.name
如果我像这样使用进程替换:
var=<(pwd)
echo $var
/dev/fd/63
据我了解,进程替换主要在程序不接受 STDIN 时使用。我不清楚进程替换到底做什么以及为什么它分配/dev/fd/63
给var
.
答案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
。