如果没有 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);
}
我正在通过系统调用了解 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);
}