已知命令从fd0读入,从fd1输出
下面这个例子引入问题
echo 'sometext' > text
exec 3>&1
#fd3=fd1(==stdout)
$date 1>&3 | cat 3>&1 1>file
#建立管道pipe0,使左侧fd1=pipe0,右侧fd0=pipe0
#管道左侧: 初始fd1==pipe0, fd3==stdout
# 最终fd1=fd3(==stdout),date输出到stdout
#管道右侧: 初始fd1==stdout, fd3==stdout
# 最终fd3=fd1==stdout, fd1=file,cat无输入,输出到file
#执行结果:
2011年 11月 22日 星期二 21:27:28 CST
$cat file
$(date 1>&3 | cat) 3>&1 1>file
#外层shell中fd3=fd1==stdout, fd1=file,这个描述符会拷贝到括号建立的内层shell。
#建立管道,使左侧fd1=pipe0,右侧fd0=pipe0
#管道左侧: 初始fd1==pipe0, fd3==stdout
# 最终fd1=fd3(==stdout),date输出到stdout
#管道右侧: fd1==file, fd3==stdout,cat输出到file
#执行结果:
2011年 11月 22日 星期二 21:29:43 CST
$cat file
$date 1>&3 | cat 1>file 3>&1
#建立管道pipe0,使左侧fd1=pipe0,右侧fd0=pipe0
#管道左侧: 初始fd1==pipe0, fd3==stdout
# 最终fd1=fd3(==stdout),date输出到stdout
#管道右侧: 初始fd1==stdout, fd3==stdout
# 最终fd1=file, fd3=fd1==file,cat输出到file
#执行结果:
2011年 11月 22日 星期二 21:30:17 CST
$cat file
$(date 1>&3 | cat) 1>file 3>&1
#外层shell中fd1=file, fd3=fd1==file,这个描述符会拷贝到括号建立的内层shell。
#建立管道,使左侧fd1=pipe0,右侧fd0=pipe0
#管道左侧: 初始fd1==file, fd3==file
# 最终fd1=fd3(==file),date输出到file
#管道右侧: fd1==file, fd3==file,cat输出到file
#执行结果:
$cat file
2011年 11月 22日 星期二 21:30:32 CST
$
于是有以下解释:
被括号包住会建立一个shell,且为包住它的shell的子shell;
子shell的建立会继承父shell的环境;
建立过后首先确立管道,将左右侧的fd1和fd0分别定位到管道上;
然后每个命令的重定向从左至右依次进行;
最后执行命令,命令从fd0取得输入,输出到fd1