为什么将stdin、stdout和stderr合并为一个文件描述符?

4
我在APUE看到了这段代码片段。 dup2(fd,0); dup2(fd,1); dup2(fd, 2); if (fd > 2) close(fd); 据我理解,它将stdin、stdout和stderr都指向了fd。它说很多程序都包含这个代码,为什么?它有什么功能?

这可以用于守护进程。 - Slava Zhuyko
我知道守护进程在后台运行,但它如何利用这段代码片段? - Sili
1
您可以查看这个 - Slava Zhuyko
1
因为守护进程不再与终端相关联,所以它们通常将输出写入日志,而不是写入stdout或stderr。而且,它们通常不从stdin读取,而是从套接字读取。 - James
2个回答

2

我会在这里添加评论和回答,因为尽管他们是正确的,但我仍然很难理解何时以及为什么需要这些调用序列。

当进程作为守护进程运行时,通常会使用此函数调用序列。在这种情况下,守护进程不希望将标准I/O文件描述符附加到终端(或其他资源)。为了“分离”这些描述符,可能会发生以下类似的事情:

int fd;  

fd = open("/dev/null",O_RDWR);  // missing from APUE exercise 3.4 example

if (fd != -1)   
{     
  dup2 (fd, 0);  // stdin  
  dup2 (fd, 1);  // stdout
  dup2 (fd, 2);  // stderr

  if (fd > 2) close (fd);  
}  

这个命令将/dev/null绑定到每个标准I/O描述符上,并关闭用于最初打开/dev/null的临时描述符(只要该打开没有因某种原因使用通常用于标准I/O描述符的描述符之一)。现在,守护进程具有有效的stdin/stdout/stderr描述符,但它们不指向可能干扰其他进程的文件或设备。

0

这主要用于守护程序,因为守护程序没有连接终端或tty。所以我们需要将错误或打印语句维护在一个文件中。因此我们才使用这些语句。在我们的系统中,文件描述符0、1、2已经分配给标准缓冲区,如stdin等...

dup2函数与dup函数有所不同。 在dup2函数中,我们不需要关闭已经使用的文件描述符。

在dup2函数中,如果第二个参数文件描述符已经在使用,则dup2会关闭第二个参数fd并分配第一个参数fd的副本,而无需使用close()函数。

然后第一个参数fd连接到第二个fd,并执行第一个fd的工作。

例如,dup2(fd,1)表示文件描述符的工作被复制到stdout。fd包含任何语句都会打印到stdout。


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