OnWorks Linux 和 Windows 在线工作站

商标

工作站免费在线托管

<上一页 | 内容 | 下一页>

过程替换

虽然它们看起来很相似,并且都可以用来组合流以进行重定向,但组命令和子 shell 之间有一个重要的区别。 组命令在当前 shell 中执行其所有命令,而子 shell(顾名思义)在当前 shell 的子副本中执行其命令。 这意味着环境被复制并提供给shell 的一个新实例。 当子shell退出时,环境的副本将丢失,因此对子shell的环境所做的任何更改(包括变量赋值)也将丢失。 因此,在大多数情况下,除非脚本需要子 shell,否则组命令比子 shell 更可取。 组命令既更快又需要更少的内存。

我们在第 28 章看到了一个子 shell 环境问题的例子,当时我们发现一个 管道中的命令并不像我们直观预期的那样工作。 回顾一下,如果我们构建这样的管道:



echo "foo" | 读回声 $REPLY

echo "foo" | 读回声 $REPLY


的内容 回复 变量总是空的,因为 命令在子shell中执行,它的副本 回复 当子shell终止时被销毁。

因为管道中的命令总是在子 shell 中执行,任何分配变量的命令都会遇到这个问题。 幸运的是,shell 提供了一种奇特的扩展形式,称为 过程替代 可用于解决此问题。

进程替换以两种方式表示: 对于产生标准输出的进程:

<(名单)

或者,对于接收标准输入的进程:

>(名单)

协调 名单 是一个命令列表。

为了解决我们的问题 ,我们可以像这样使用进程替换:


读 < <(echo "foo") echo $REPLY

读 < <(echo "foo") echo $REPLY


进程替换允许我们将子shell 的输出视为用于重定向的普通文件。 事实上,既然它是一种扩展形式,我们可以考察它的真正价值:



[me@linuxbox ~]$ echo <(echo "foo")

/开发/fd/63

[me@linuxbox ~]$ echo <(echo "foo")

/开发/fd/63


通过使用 回音 查看扩展的结果,我们看到子shell的输出是由一个名为的文件提供的 /开发/fd/63.

进程替换通常与包含以下内容的循环一起使用 . 这是一个例子

处理由子shell创建的目录列表内容的读取循环:


#!/斌/庆典


# pro-sub:进程替换演示


而读取 attr 链接所有者组大小日期时间文件名; 做猫<<- EOF

文件名:$filename 大小:$size

所有者:$owner

组:$group 修改:$date $time 链接:$links 属性:$attr


EOF

完成 < <(ls -l | tail -n +2)

#!/斌/庆典


# pro-sub:进程替换演示


而读取 attr 链接所有者组大小日期时间文件名; 做猫<<- EOF

文件名:$filename 大小:$size

所有者:$owner

组:$group 修改:$date $time 链接:$links 属性:$attr


EOF

完成 < <(ls -l | tail -n +2)


循环执行 对于目录列表的每一行。 列表本身是在脚本的最后一行生成的。 此行将进程替换的输出重定向到循环的标准输入。 这 尾巴 命令包含在进程替换管道中以消除列表的第一行,这是不需要的。

执行时,脚本会产生如下输出:



[我@linuxbox ~]$ 亲子| 头-n 20

文件名:addresses.ldif 大小:14540

业主:我

组:我

Modified: 2009-04-02 11:12

[我@linuxbox ~]$ 亲子| 头-n 20

文件名:addresses.ldif 大小:14540

业主:我

组:我

Modified: 2009-04-02 11:12


链接

1

链接


属性:-rw-r--r--


文件名:bin

大小:4096

业主:我

组:我

Modified: 2009-07-10 07:31

链接:2

属性:drwxr-xr-x


文件名:bookmarks.html 大小:394213

业主:我

组:我

属性:-rw-r--r--


文件名:bin

大小:4096

业主:我

组:我

Modified: 2009-07-10 07:31

链接:2

属性:drwxr-xr-x


文件名:bookmarks.html 大小:394213

业主:我

组:我


图片

OnWorks 的顶级操作系统云计算: