shell 进程替换
进程替换和命令替换非常相似。命令替换是把一个命令的输出结果赋值给另一个变量,例如dir_files=`ls -l`
或date_time=$(date)
;而进程替换则是把一个命令的输出结果传递给另一个(组)命令。
0.shell进程替换的用法
写法 | 含义 | 注意点 | 本质 |
---|---|---|---|
<(commands) | 它借助于输入重定向,可以将它的输出结果作为另一个命令的输入 | commands 是一组命令列表,多个命令之间以分号; 分隔。注意,< 或> 与圆括号之间是没有空格的。 | /dev/fd/n文件接受(commands)的输出,作为另一个命令的输入 |
>(commands) | 它借助于输出重定向,可以接受另一个命令的标准输出结果 | 从/dev/fd/n文件中读取内容,作为(commands)的输入 |
1.使用进程替换的必要性
举栗 | 结果 | 说明 |
---|---|---|
普通模式
| 输出结果为空 | echo 命令在父 Shell 中执行,而 read 命令在子 Shell 中执行,当 read 执行结束时,子 Shell 被销毁,AA 变量也就消失了。 管道中的命令总是在子 Shell 中执行的,任何给变量赋值的命令都会遭遇到这个问题。 |
使用进程替换
| 输出结果为aaaaa | 整体上来看,Shell 把echo "aaaaa" 的输出结果作为 read 的输入。<() 用来捕获 echo 命令的输出结果,< 用来将该结果重定向到 read。注意,两个 < 之间是有空格的,第一个< 表示输入重定向,第二个< 和() 连在一起表示进程替换。read 命令和第二个 echo 命令都在当前 Shell 进程中运行,读取的数据也会保存到当前进程的 AA 变量,所以使用 echo 能够成功输出。 |
进程替换用作「接受标准输入」的例子 echo "qpy" > >(read; echo "你好,$REPLY") | 运行结果:你好,qpy | 因为使用了重定向,read 命令从echo "qpy" 的输出结果中读取数据。 |
2.进程替换的本质
为了能够在不同进程之间传递数据,实际上进程替换会跟系统中的文件关联起来,这个文件的名字为/dev/fd/n
(n 是一个整数)。该文件会作为参数传递给()
中的命令,()
中的命令对该文件是读取还是写入取决于进程替换格式是<
还是>
:
- 如果是
>()
,那么该文件会给()
中的命令提供输入;借助输出重定向,要输入的内容可以从其它命令而来。 - 如果是
<()
,那么该文件会接收()
中命令的输出结果;借助输入重定向,可以将该文件的内容作为其它命令的输入。
使用 echo 命令可以查看进程替换对应的文件名:
命令 | 输出 | 说明 |
---|---|---|
echo >(true) | /dev/fd/63 | /dev/fd/ 目录下有很多序号文件,进程替换一般用的是 63 号文件,该文件是系统内部文件,我们一般查看不到。
|
echo <(true) | /dev/fd/63 | |
echo >(true) <(true) | /dev/fd/63 /dev/fd/62 | |
echo "qpy" > >(read; echo "hello, $REPLY") | hello, qpy | 第一个
|