【问题标题】:Redirecting STDIN/OUT/ERR重定向标准输入/输出/错误
【发布时间】:2016-12-02 16:20:46
【问题描述】:

我正在尝试在 c 中创建一个 linux 守护程序,并找到了一些 sample code on this page

除了尝试将 STDIN、STDOUT 和 STDERR 重定向(到 /dev/null/)的位置之外,我了解所有代码。我还在这里发现了一些与为什么这些应该被重定向(我理解)相关的问题。

我的问题涉及的具体代码部分是:

/* Route I/O connections */

/* Open STDIN */
i = open("/dev/null", O_RDWR);

/* STDOUT */
dup(i);

/* STDERR */
dup(i);

读取man page for dup() 意味着dup() 只是复制了一个文件描述符。

所以我不明白这是如何重定向的?编译器是从上面一行中的 cmets 中获取提示吗?还是缺少一些代码?是完全错误吗?还是我错过了什么?

【问题讨论】:

标签: c linux


【解决方案1】:

了解您链接到的示例代码的前面部分很重要:

/* close all descriptors */
        for (i = getdtablesize(); i >= 0; --i)
        {
            close(i);
        }

这将关闭所有打开的文件描述符,包括 STDINSTDOUTSTDERR

作为open() 状态的手册页

成功调用返回的文件描述符将是当前未为进程打开的编号最小的文件描述符

因此,示例代码中对open() 的后续调用会将文件描述符0(即STDIN)重定向到/dev/null

随后对dup() 的调用将使用下一个最小数字复制文件描述符。 STDOUT1STDERR2

dup() 的手册页指出:

dup() 系统调用创建文件描述符 oldfd 的副本,使用编号最小的未使用描述符作为新描述符

【讨论】:

    【解决方案2】:

    来自 dup 的手册页:

    dup(oldfd) 系统调用创建文件描述符 oldfd 的副本, 为新描述符使用编号最小的未使用描述符。

    如果你看到引用的代码,他是先关闭所有打开的文件描述符:

          for (i = getdtablesize(); i >= 0; --i)
             {
                close(i);
             }
    

    之后,当您调用dup(i) 时,它会将文件描述符 i 复制到最低的可用描述符,即 0 (stdin)。再次这样做会将其复制到描述符 1 (stdout) 和描述符 2 (stderr)。这样守护进程的stdinstdoutstderr就指向了/dev/null

    每个进程都会获得三个打开的​​文件描述符,它们是stdinstdoutstderr(这些描述符通常分别具有值 0、1 和 2)。例如,当您调用printf() 时,它会写入stdout 描述符指向的文件。通过将此描述符指向另一个文件(例如/dev/null),该进程的任何输出都将被重定向到该文件。同样的逻辑适用于stdinstderr

    在 shell 上,当你运行 ls > ls.out 之类的东西时,shell 也会做同样的事情。它fork()s 一个新进程,打开ls.out 进行写入,并调用dup(或dup2)将ls.out 的文件描述符复制到该进程的stdout。

    【讨论】:

      猜你喜欢
      • 2022-07-23
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多