如果没有 dup 也可以实现相同的目的,为什么我需要使用 dup 进行 stdout 重定向?

Why do I need to use dup for stdout redirection if the same can be achieved without it?

我正在通过系统调用了解 Linux 中的重定向。将 stdout 重定向到文件“foo.txt”的常见方法是这样做:

int fd = creat("foo.txt", 0644);    
close(1);
dup(fd);
close(fd);
execlp("ls", "ls", NULL);

然而我根据经验发现,我们甚至可以在不使用 dup 的情况下实现同样的事情。

close(1);
creat("foo.txt", 0644); 
execlp("ls", "ls", NULL);   

第二个示例每次都会正确运行,因为总是创建 returns 最低的未使用文件描述符。 我想知道为什么我看到的每个例子都更喜欢第一种方式,如果 secnods 更简单?

这两个例子都是错误的,因为它们都依赖于相同的无效假设,即关闭 1 使 1 成为最低可用 FD。

您可以轻而易举地使这个假设无效,导致程序失败:

$ cat foo.c
#include <fcntl.h>
#include <unistd.h>

void main() {
  close(1);
  creat("foo.txt", 0644);
  execlp("ls", "ls", NULL);
}

$ gcc foo.c -o foo

$ ./foo 0>&-
ls: write error: Bad file descriptor

处理这个问题的方法是使用dup2明确选择你想要的fd:

void main() {
  int fd = creat("foo.txt", 0644);
  if (fd != 1) {
    dup2(fd, 1);
    close(fd);
  }
  execlp("ls", "ls", NULL);
}