我试图了解系统调用dup()的工作原理。我问这个问题,因为我在C中编写一个shell,我需要将STDOUT重定向到一个文件。这是正确的方法吗?
例如,如果我有以下代码:
remember = dup(STDOUT_FILENO);
fileDescriptor = open("file.txt",O_RDONLY);
那么写入stdout的所有内容现在都会写入打开的文件?
执行以下行后:
remember = dup(STDOUT_FILENO);
从文件描述符表中删除STDOUT_FILENO,使第一个点为空。打开新文件时,最早的空文件描述符将被指定给这个新打开的文件,因此在这种情况下为1.
答案 0 :(得分:1)
不。您只需复制stdout的文件描述符。
使用到目前为止的代码,您现在可以执行写入记忆,输出也将转到控制台:
char str = "this now goes to console, too!";
write(remember, str, strlen(str));
如果要重定向控制台输出,则必须执行此操作:
dup2(fileDescriptor, STDOUT_FILENO);
这将关闭STDOUT_FILENO
(但如果需要,您在remember
中有一个副本可以恢复它)并用fileDescriptor
覆盖它 - 从现在开始,控制台输出转到文件...
如果您没有考虑过将输出恢复到控制台,则可以完全忽略对dup
的第一次调用...
编辑(响应您的编辑):
从文件描述符表中删除STDOUT_FILENO,使第一个点为空。打开新文件时,最早的空文件描述符将被指定给这个新打开的文件,因此在这种情况下为1.
这适用于close(STDOUT_FILENO)
!
如果不想恢复那么回过头来:你也可以这样做:
close(STDOUT_FILENO);
fileDescriptor = open("file.txt",O_WRONLY | O_CREAT);
// fileDescriptor will be 1 now
顺便说一下:你必须打开你的文件,启用写访问权限(O_WRONLY或O_RDWR),因为你想写入该文件(重定向输出到)!
对于文件尚不存在的情况,您需要O_CREAT标志。如果您不想清除该文件,但追加,请添加O_APPEND标记(请参阅open)。
答案 1 :(得分:0)
没有dup
用于复制现有描述符并返回一个副本,其值在自由描述符中较少(某些文档说``返回的新描述符电话是最低的
编号描述符当前未被进程使用。''),所以:
fileDescriptor = open("file.txt",O_RDONLY); // get new desc.
close(STDIN_FILENO); // close 0
dup(fileDescriptor); // dup new desc to 0 (less possible free desc).
// here fileDescriptor and 0 are aliases to the same opened file
close(fileDescriptor); // free unused desc.