mrk*_*afk 1 bash shell redirect
man bash在重定向时这样说:
请注意,重定向的顺序很重要。例如,命令
Run Code Online (Sandbox Code Playgroud)ls > dirlist 2>&1将标准输出和标准错误定向到文件目录列表,而命令
Run Code Online (Sandbox Code Playgroud)ls 2>&1 > dirlist仅将标准输出定向到文件 dirlist,因为在将标准输出重定向到 dirlist 之前,标准错误是从标准输出复制的。
我真的不明白这部分:
在标准输出重定向到 dirlist 之前,标准错误已从标准输出复制。
从我的角度来看,>这只是意味着重定向,比如ls > dirlist将输出重定向ls到 file dirlist。
因此2>&1应该将 stderr 重定向到 stdout,然后将其重定向到dirlist( > dirlist)。然而,显然只有标准输出被重定向到dirlist那时。
这个“从流 B 复制的流 A”有什么关系?
Shell 重定向实际上只是调用 syscall dup2()。引用自https://man7.org/linux/man-pages/man2/dup.2.html --
int dup2(int oldfd, int newfd);dup() 系统调用分配一个新的文件描述符,该描述符引用与描述符 oldfd 相同的打开文件描述。
这实际上并没有做任何类似于“重定向流”的事情——相反,它正在更改打开文件的表,以使表中一个位置的文件句柄从表中的另一个位置指向。
那么,让我们看一下你的第一个例子,ls > dirlist 2>&1
dirlist用open(2).dup2()用于将创建的文件句柄复制open()到FD 1(默认>),并且关闭动态创建的句柄。dup2()用于将 FD 1 复制到 FD 2。...最终结果:FD 1 和 FD 2 都指向dirlist。
现在,让我们看看你的下一个例子,ls 2>&1 >dirlist
dup2()用于将之前在 FD 1 中打开的内容复制到 FD 2open()用于打开文件dirlistdup2()用于将dirlist上的句柄复制到FD 1,并关闭动态创建的句柄。...最终结果:FD 2 现在指向 FD 1 的先前值,FD 1 现在指向dirlist。