如何在C中关闭stdout和stderr?

cho*_*hoc 11 c stdout stderr

我需要为我的一个C程序关闭stdout和stderr.如果不退出程序执行,怎么可能?

小智 47

你可以:

fclose(stdout);
fclose(stderr);
Run Code Online (Sandbox Code Playgroud)

对于任何想知道你为什么要这样做的人来说,这对于Unix上的守护进程/服务进程来说是一个相当普遍的任务.

但是,您应该知道关闭文件描述符可能会产生意想不到的后果:

  • 当您打开新文件时,将使用这些现在可用的描述符.因此,例如,如果您随后fopen该文件描述符(至少在Linux上)将替换fd 1,即stdout.随后使用此代码的任何代码都将写入此文件,这可能与您的意图不同.
  • 请参阅R ..对文件描述符与C库FILE*指针的评论.特别:
    • 如果你在Linux下写一个封闭的fd,你会收到一个错误,但是:
    • 如果你使用一个使用stdoutor 的C库函数stderr(它们是FILE*指针(参见它们的定义),那么在FILE*关闭时写入这些函数是未定义的行为.这可能会以意想不到的方式崩溃你的程序,而不是总是在错误点.请参阅未定义的行为.
  • 您的代码不是唯一受影响的部分.您使用的任何库以及您启动的继承这些文件描述符作为其标准描述符的任何进程也会受到影响.

快速的单线解决方案freopen()就是说/dev/null,/dev/console在Linux/OSX或nulWindows下.或者,您可以根据需要使用特定于平台的实现重新打开文件描述符/句柄.

  • 你弄错了.写入已关闭的"FILE"(stdio流)是UB,但写入已关闭的文件描述符只是"EBADF".在任何情况下,更重要的原因是程序或子进程的另一部分可能稍后打开一个重要文件,该文件将被分配第一个未使用的文件描述符编号.如果未使用fd 0,1或2,则新文件描述符将取代stdin,stdout或stderr,并且可能被程序(或子进程)的其他部分破坏,这些部分使用其中任何一个通常目的... (7认同)
  • 使用freopen("/ dev/null","r",stdin); ,见男人freopen() (7认同)
  • ...这样做的原因是将进程与启动它的tty取消关联(如果它是从tty开始的). (3认同)
  • @NicholasWilson是的,我知道.我当时解决了这个问题,为了使其更明确,我重新编写了答案,以纳入上述所有评论. (2认同)

lhf*_*lhf 8

你有什么尝试?不起作用fclose

  • 你可以使用freopen("/ dev/tty","w",stdout)重新打开它; 如果对execl的调用失败,通常会使用此方法. (3认同)
  • @entropy,没有办法再打开它. (2认同)