当前位置: 技术问答>linux和unix
求解惑,Linux管道和重定向
来源: 互联网 发布时间:2017-03-23
本文导语: 最近看到一篇关于管道的文章中有这样的描述: alias testcmd='command ls -ld / xxx ~/.bashrc yyy' # swap stdout & stderr stream, i.e. # let the stderr stream pass through a pipe while the stdout is printed to the terminal only ...
最近看到一篇关于管道的文章中有这样的描述:
在我的RHEL上输出是这样的:
drwxr-xr-x 26 root root 4096 Oct 7 22:37 /
-rw-r--r-- 1 admin root 497 Aug 14 14:31 /home/admin/.bashrc
LS: XXX: NO SUCH FILE OR DIRECTORY
LS: YYY: NO SUCH FILE OR DIRECTORY
1>&3 3>&-这句,关闭3并不会导致1被block,由此可见,1>&3并不是一个套接的效果,而是一个赋值。也就是说,1->stdout, 运行1>&3之后,得到的是3->stdout,而不是1->3->stdout。那么问题是,2>&1 1>&3将导致1和2都指向stdout,bash如何鉴别谁需要进入管道?
我有一种猜想,就是因为有管道符的存在,所以testcmd 2>&1中的&1其实已经不再指stdout,而是作为tr命令的输入管道。大家觉得对么?元方,你怎么看?
alias testcmd='command ls -ld / xxx ~/.bashrc yyy'
# swap stdout & stderr stream, i.e.
# let the stderr stream pass through a pipe while the stdout is printed to the terminal only
# cf. http://tldp.org/LDP/abs/html/io-redirection.html:
# "Child processes inherit open file descriptors. This is why pipes work.
# To prevent an fd from being inherited, close it."
(
exec 3>&1
testcmd 2>&1 1>&3 3>&- | tr '[[:lower:]]' '[[:upper:]]' 3>&-
exec 3>&-
)
在我的RHEL上输出是这样的:
drwxr-xr-x 26 root root 4096 Oct 7 22:37 /
-rw-r--r-- 1 admin root 497 Aug 14 14:31 /home/admin/.bashrc
LS: XXX: NO SUCH FILE OR DIRECTORY
LS: YYY: NO SUCH FILE OR DIRECTORY
1>&3 3>&-这句,关闭3并不会导致1被block,由此可见,1>&3并不是一个套接的效果,而是一个赋值。也就是说,1->stdout, 运行1>&3之后,得到的是3->stdout,而不是1->3->stdout。那么问题是,2>&1 1>&3将导致1和2都指向stdout,bash如何鉴别谁需要进入管道?
我有一种猜想,就是因为有管道符的存在,所以testcmd 2>&1中的&1其实已经不再指stdout,而是作为tr命令的输入管道。大家觉得对么?元方,你怎么看?
|
重定向其实是个文件描述符dup的过程,以你的例子而言:
testcmd 1>>log 2>&1
这个命令是先把log的文件描述符dup给fd1,此时fd1的文件表项指向的就是log文件,再把fd1 dup给fd2,这样fd2也指向了log文件
testcmd 2>&1 1>>log
这个命令先把fd1 dup给了fd2, 这样fd1和fd2的文件表项指向的都是终端设备,再把log的文件描术符dup给fd1,这样fd2仍然指向终端设备,fd1指向了log文件
testcmd 1>>log 2>&1
这个命令是先把log的文件描述符dup给fd1,此时fd1的文件表项指向的就是log文件,再把fd1 dup给fd2,这样fd2也指向了log文件
testcmd 2>&1 1>>log
这个命令先把fd1 dup给了fd2, 这样fd1和fd2的文件表项指向的都是终端设备,再把log的文件描术符dup给fd1,这样fd2仍然指向终端设备,fd1指向了log文件