unix 子进程中的stdout和stderr重定向

uklbhaso  于 2022-12-12  发布在  Unix
关注(0)|答案(3)|浏览(209)

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

./script.sh 2>&1

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

3yhwsihp

3yhwsihp1#

在UNIX/Linux上创建一个子进程使用一个通常称为 fork 的过程。它的作用是将当前进程的几乎整个进程地址空间(程序代码、数据,几乎所有内容)复制到子进程中。子进程中的进程标识符(PID)不同,但几乎所有其他内容都相同。
在一个被复制的进程中有一个项目是 * 文件描述符表 *。这就像一个数组。每个打开的文件都有一个条目,按照惯例,前三个0、1、2是 * 标准流 *、stdin、stdout、stderr。这解释了2>&1中使用的数字。当我们进行重定向时,这是由shell完成的,因为在这个阶段我们的子进程是另一个shell进程。
现在是神奇的部分,通常称为 exec。如果我们想运行一个不同的 * 程序 *,比如ls,我们可以在进程中切换程序。所以现在新程序从头开始,但是保留了某些核心项。比如用户、组、当前目录、umask和文件描述符表都保留下来供新程序使用。
因此,如果文件描述符表以前被修改过,新程序会继承这些修改。没有什么可以阻止程序覆盖这些设置并使用不同的文件,但这种情况很少发生。
所有这些行为都是默认的。程序可以改变哪些文件描述符和其他项被保留在fork/exec边界上,但它们通常不会。

u91tlkcl

u91tlkcl2#

答案很简单,你可以自己试试:

$ (>&1 echo "STDOUT is gone"; >&2 echo "I'm still here") > /dev/null
I'm still here

STDOUT的父进程[我正在启动一个新的shell,其中包含大括号:() ]将被发送到/dev/null,所有子级的STDOUT也将被发送到/dev/null

xdnvmnnf

xdnvmnnf3#

./script.sh 2>&1 &
考虑到我的情况,这对我来说效果很好。我不确定这些子进程是否也将它们的stderr重定向到stdout。

相关问题