假设我有一个名为fstatcheck的程序。它从命令行获取一个参数并将其视为文件描述符。它检查文件描述符指向的文件的统计信息。
例如:
$./fstatcheck 1
l = 1
type: other, read: yes
另一个例子:
$./fstatcheck 3 < foobar.txt
l = 3
Fstat error: Bad file descriptor
问题:
shell在第二个例子中做了什么? 我可以猜测它需要3作为文件描述符并开始分析stat,但描述符3没有打开。但shell如何处理重定向?
我假设shell执行以下算法:
if (fork() == 0) {
// What does the shell do here?
execve("fstatcheck", argv, envp);
}
有没有办法可以创建文件描述符3并让它连接到一个打开的文件表,只需使用shell命令(而不是使用C代码)就可以指向foobar.txt文件stat?
答案 0 :(得分:4)
让我们找出strace
:
$ strace sh -c 'cat < /dev/null'
[...]
open("/dev/null", O_RDONLY) = 3
fcntl(0, F_DUPFD, 10) = 10
close(0) = 0
fcntl(10, F_SETFD, FD_CLOEXEC) = 0
dup2(3, 0) = 0
close(3) = 0
[...]
execve("/bin/cat", ["cat"], [/* 28 vars */]) = 0
[...]
因此,在您的代码中,相关部分将是:
if (fork() == 0) {
int fd = open(filename, O_RDONLY); // Open the file
close(0); // Close old stdin
dup2(fd, 0); // Copy fd as new stdin
close(fd); // Close the original fd
execve("fstatcheck", argv, envp); // Execute
}
至于打开另一个fd,绝对是:
myprogram 3< file
这将打开file
以阅读该程序的fd 3。仅<
是0<
的同义词。