看如下一段代码,使用进程替换,可以避免使用管道引起的subshell,subshell不能修改当前shell的变量,有时候会带来不便。有了进程替换,我们就方便多了。
#!/bin/bash
#we use pipe, it will generate two subshell, so the while loop runs
#in a subshell, in which, it changes commands1 in the subshell which is not the
#commands1 of the current shell, as a result , we failed to change the commands1
#of the current shell
declare -a commands1
i=0
echo -e "line1\nline2" | while read aline ;
do
commands1[$i]=$aline
echo "commands1[$i]: ${commands1[$i]}"
i=$((i+1))
done
echo "outside loop commands1 has ${#commands1[@]} elements"
echo "outside loop commands1[0]=${commands1[0]}"
echo -e "\n\n"
这里,我们使用了pipe,会引起subshell,导致当前shell的commands1并不能被修改。
#get input from a file, so we run the while loop in the current shell,
#we can change the commands2 of the current shell
declare -a commands2
i=0
while read aline;
do
commands2[i]=$aline
echo "commands2[$i]=${commands2[$i]}"
i=$((i+1))
done
echo "outside loop commands2 has ${#commands2[@]} elements"
echo "outside loop commands2[0]=${commands2[0]}"
echo -e "\n\n"
这里,我们用一个重定向,读取文件中的内容,当然就是在当前shell里面,就可以改变当前shell的变量。由这里的特点,再结合进程替换的概念,我们就有了如下解决办法:
#we replace the file with a process. and the while loop still runs
#in the current shell, so we can change the commands3 array of the
#current shell.
declare -a commands3
i=0
while read aline;
do
commands3[i]=$aline
echo "commands3[$i]=${commands3[$i]}"
i=$((i+1))
done< <(echo -e "line1\nline2")
echo "outside loop commands3 has ${#commands3[@]} elements"
echo "outside loop commands3[0]=${commands3[0]}"
这里我们首先使用重定向,将标准输入重定向到某个文件,然后再文件参数的位置处使用<(echo -e xxxx) 命令。从而实现进程替换。
进程替换的概念: 进程替换与很相似.
命令替换把一个命令的结果赋值给一个变量,
比如dir_contents=`ls -al`或xref=$(
grep word datafile).
进程替换把一个进程的输出提供给另一个进程(换句话说,
它把一个命令的结果发给了另一个命令).
格式:
>(command)
<(command)
进程替换需要放置在一个命令的文件参数的位置,比如diff file1 file2就可以使用进程替换,这样我们就不是比较两个文件了,而是比较两个进程的输出:
diff <(cmd1) <(cmd2)
然而对于diff来说,她什么都不知道。
实现原理:cmd执行时,将其标准输出重定向到/dev/fd/n的一个文件,而diff就读取n这个文件描述符,即将其标准输入重定向到了/dev/fd/n。所以diff还以为他是通过文件读取的内容。
进程替换与命令替换的区别:
命令替换有:$(cmd) 或者 `cmd`区别是,命令替换直接将命令的结果放在这里,而进程替换是将结果写入一个文件,而其他命令去读取这个文件。命令替换一般用来将执行结果赋值给一个变量,而进程替换一般用来将运行结果交给另一个命令去执行但是不能使用管道pipe.即不使用subshell。
阅读(2587) | 评论(0) | 转发(0) |