【问题标题】:understanding stdout, stderr and stdin了解标准输出、标准错误和标准输入
【发布时间】:2014-07-22 10:13:05
【问题描述】:
root@C6903:/ # ls -l /proc/327/fd/
lrwx------ root     root              1970-02-11 01:40 0 -> /dev/null
lrwx------ root     root              1970-02-11 01:40 1 -> /dev/null
lrwx------ root     root              1970-02-11 01:40 2 -> /dev/null

如我所见,all(0, 1, 2) 都指向 /dev/null。为什么?它们在内部有何不同?

在我的情况下(Coredump 环境),fd 的列表是这样的。

root@C6903:/ # ls -l /proc/5987/fd/                            
lr-x------ root     root              1970-02-11 01:34 0 -> pipe:[31608]

所以 stdout 和 stderr 文件不存在。在这种情况下,如果我给出printf(),我将面临未定义的行为(其他打开的文件被覆盖)。为了解决这个问题, 我正在做如下的事情:

int check_fd(int fd)
{
    return (fcntl(fd, F_GETFD) != -1);
}

...

    if (!check_fd(STDOUT_FILENO))
        fopen("/dev/null", "w");

    if (!check_fd(STDERR_FILENO))
        fopen("/dev/null", "w");

这运作良好。但我害怕如果我做错了什么。如果我必须打开它们,如何区分 stdout 和 stderr?

【问题讨论】:

  • man freopen。简单地调用 fopen 可能会打开一个以 1 或 2 作为底层文件描述符的文件,但这并不能满足您的要求。

标签: linux file unix operating-system


【解决方案1】:

stdoutstdinstderr根据程序的启动方式指向不同的管道或套接字。在第一种情况下,它们都被重定向到/dev/null,因此标准输出上没有任何输出,而对于输入,使用/dev/null是传递空文件的便捷方式。

如果您需要区分它们,则需要将它们重定向到不同的文件。在这种情况下,对两者都使用/dev/null 并不是一个好主意。例如,您可以打开两个不同的文件:program.stdoutprogram.stderr,然后分别写入每个文件

【讨论】:

  • '没有任何输出'是不正确的。从程序的角度来看,它是在愉快地写数据,从程序内存到内核内存有IO。该数据被内核丢弃,但由于它是从用户空间复制到内核空间,因此说“没有输出”是不准确的。
  • 我的意思是标准输出上没有输出
  • 但是标准输出有输出!数据被丢弃的事实并不意味着它永远不会从进程中获得输出。
  • 是的,我知道,我的意思是数据被丢弃而不是显示在标准输出上
  • 您似乎认为“stdout”是一种显示设备,这是我试图纠正的误解。数据写入标准输出。在这种情况下(在许多情况下,可能是大多数情况下),st​​dout 不是 tty。
【解决方案2】:

如果 stdout 和 stderr 已关闭,您想重新打开它们,请尝试:

freopen( "/dev/null", "w", stdout );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    相关资源
    最近更新 更多