【问题标题】:Get file descriptor of stdout c获取标准输出 c 的文件描述符
【发布时间】:2019-12-05 04:16:12
【问题描述】:

stdin、stdout、stderr 文件描述符默认为 0、1 和 2。但是,当我通过fd = open(foo, 0) 打开一个文件后,我发现fd 现在是 1。1 用于新的文件描述符。现在标准输出文件描述符是什么?或者它已关闭,我需要重新打开它?如果是,如何?有没有办法保留 0、1、2 个文件描述符并从 3 中使用?

/* readslow from the book with my "improve": the unix programming environment */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define SIZE 512
int main (int argc, char *argv[])
{
    char buf[SIZE];
    int n, fd;
    int t = 10;

    if ((argc > 1) && (fd = open(argv[1], 0) == -1)) {error("can't open %s", argv[1]);}
    fprintf(stderr, "%d", fd);

    for (;;) {
        while ((n = read(fd, buf, sizeof buf)) > 0)
           write(1, buf, n);
        sleep(t);
    }
}

fprintf(stderr, "%d", fd)会给我1个。

【问题讨论】:

  • 请显示产生该结果的代码。即,请提供minimal reproducible example
  • @kaylum 我用我的代码更新了我的问题。
  • 都是我的错。我想念if ((argc &gt; 1) &amp;&amp; (fd = open(argv[1], 0) == -1)) 中的“)”。真的很难找到这个错误。对不起

标签: c shell


【解决方案1】:

[撰写此答案时,问题中没有代码。我已经接受了 OP 的说法,即 open 返回的文件描述符是 1,由于括号放错了,事实证明这是不真实的。]

我发现 fd 现在是 1。1 用于新的文件描述符。

发生这种情况的唯一方法是关闭 fd 1。

什么是标准输出文件描述符?

fileno(stdout) 将为您提供与句柄关联的fd

有没有办法保留 0、1、2 的文件描述符并使用 from 3?

如果不关闭 fd 0、1 和 2,它们将不会被重用。 open 使用编号最小的未使用文件描述符。

如果您想断开 fd 0、1 或 2,请不要关闭它们。这会导致各种问题。改为将它们重新打开到/dev/null

或者它已关闭,我需要重新打开它?如果是,怎么做?

您可以使用dup2 使一个 fd 成为另一个 fd 的别名。

【讨论】:

  • 这个答案是正确的。事实上,我发现我的代码中错过了一个“)”,这导致了这种混乱。你的回答让我更清楚文件描述符。谢谢
  • 这个答案在发布时是合理的——但随后代码被添加到问题中,这变得很切题。就目前而言它是准确的,但代码有一个与关闭文件描述符 1 或使用 dup2() 无关的主要优先级缺陷。
【解决方案2】:

您的代码包含片段:

if (argc > 1 && (fd = open(argv[1], 0) == -1))

fd 中的结果就像您在括号内写了比较:

if (argc > 1 && (fd = (open(argv[1], 0) == -1)))

所以分配给fd的结果是正确的1,因为open()返回的值确实是-1。您应该在作业周围加上括号:

if (argc > 1 && (fd = open(argv[1], 0)) == -1)

【讨论】:

  • 是的,我现在意识到了。我不是故意这样做的。愚蠢的。它有时会发生在我身上
  • 我们大多数人都曾在某个时候犯过这种错误。它确实证明了显示代码的重要性。有了代码,解释就很简单了。没有代码,我们只能进行假设——一旦代码显示,假设的内容不一定相关。
猜你喜欢
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2020-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
相关资源
最近更新 更多