在 bash 中,我使用的参数看起来像
paste <(cat file1 | sort) <(cat file2 | sort)
或者
comm <(cat file1 | sort) <(cat file2 | sort)
当我检查man comm
or时man paste
,文档说参数确实是文件。
问题:
<(cat file1 | sort)
是否为和创建了中间临时文件(在 TEMP 文件系统或较慢磁盘上的其他位置)<(cat file2 | sort)
?这个魔法的名字是什么
<( )
? (查找其文档)它是特定于 bash 还是可以跨其他 shell 工作?
答案1
这称为进程替换。
进程替换允许使用文件名引用进程的输入或输出。
进程列表异步运行,其输入或输出显示为文件名。该文件名作为扩展结果作为参数传递给当前命令。如果使用 >(list) 形式,写入文件将为列表提供输入。如果使用 <(list) 形式,则应读取作为参数传递的文件以获得 list 的输出。请注意,< 或 > 与左括号之间不能出现空格,否则该构造将被解释为重定向。支持命名管道 (FIFO) 或 /dev/fd 命名打开文件方法的系统支持进程替换。
它不仅仅是 bash 的东西,因为它最初出现在 ksh 中,但它不在 posix 标准中。
在底层,进程替换有两种实现方式。在支持
/dev/fd
(大多数类 Unix 系统)的系统上,它通过调用pipe(
) 系统调用来工作,该系统调用返回新匿名管道的文件描述符$fd
,然后创建字符串/dev/fd/$fd
,并在命令行上替换它。在不支持的系统上/dev/fd
,它会mkfifo
使用新的临时文件名来创建命名管道,并在命令行上替换该文件名。
答案2
您可以将其视为<( somecommand )
包含 的输出的临时文件的文件名somecommand
。换句话说,
utility < <( somecommand )
是一个快捷方式
somecommand >tempfile
utility <tempfile
rm -f tempfile
和
utility <( somecommand )
是一个快捷方式
somecommand >tempfile
utility tempfile # notice the lack of redirection here (utility expected to read from "tempfile")
rm -f tempfile
同样>( somecommand )
可以被认为是将被输入somecommand
到其标准输入的临时文件的文件名。换句话说,
utility > >( somecommand )
是一个快捷方式
utility >tempfile
somecommand <tempfile
rm -f tempfile
和
utility >( somecommand )
可能是一个捷径
mkfifo temppipe
somecommand <temppipe &
utility temppipe # utility is expected to write to "temppipe"
rm -f temppipe
(或类似的东西)