子进程中的stdout和stderr重定向

Tom*_*mek 0 unix bash stdout process stderr

如果我像这样运行Bash脚本:

./script.sh 2>&1
Run Code Online (Sandbox Code Playgroud)

stderr将被重定向到stdout.

如果脚本在内部调用某个工具(例如ls)或生成一个新进程,这些子进程是否stderr也将它们重定向到stdout

cda*_*rke 14

在UNIX/Linux上创建子进程使用通常称为fork的过程.这样做的目的是将当前进程的几乎整个进程地址空间(程序代码,数据,几乎所有内容)复制到子进程.进程标识符(PID)在孩子中是不同的,但几乎所有其他内容都是相同的.

复制过程中的一个项目是文件描述符表.这就像一个数组.每个文件都有一个打开的条目,按照惯例,前三个,0,1,2是标准流,stdin,stdout,stderr.这解释了使用的数字2>&1.当我们进行重定向时,正是这三个条目在孩子中发生了变化.这是由shell完成的,因为在这个阶段我们的子进程是另一个shell进程.

现在出现了神奇的部分,一般称为exec.如果我们想运行不同的程序,比如ls,我们可以在过程中切换程序.所以现在新程序从一开始就开始,但保留了某些核心项目.诸如用户,组,当前目录,umask和文件描述符表之类的内容都保留供新程序使用.

因此,如果先前已更改文件描述符表,则新程序将继承这些更改.没有什么可以阻止程序覆盖这些设置并使用不同的文件,但很少这样做.

默认情况下,所有这些行为.程序可以更改fork/exec边界中保留的文件描述符和其他项,但它们通常不会.