子进程中的标准输出和错误输出重定向

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

./script.sh 2>&1

stderr将会被重定向到stdout

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

3个回答

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

3

是的,简短回答就是这样。你可以自己尝试一下:

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

父进程的标准输出(STDOUT)[我正在使用花括号:()启动一个新的shell]将被发送到/dev/null,所有子进程的STDOUT也将如此。

0

./script.sh 2>&1 &

在我的情况下,这对我很有效。我不确定这些子进程是否也将其stderr重定向到stdout。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接