05.04 Shell 启动的程序的三大标准文件是同一个文件
#include <errno.h>
#include <fcntl.h>
#include <linux/kcmp.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
int main() {
pid_t pid = getpid(); /* always successful */
int ret = syscall(SYS_kcmp, pid, pid, KCMP_FILE, 0, 1);
int ec = errno;
if (ec) {
perror("kcmp");
return 1;
}
printf("kcmp returns %d\n", ret);
}
其中,kcmp 系统调用可以用来比较两个进程的资源大小(0 等于,1 小于,2 等于,3 不相等但无法确定大小)。输出:
kcmp returns 0
这说明此文件在终端中运行时,标准输入流和输出流使用的是相同的打开文件项(事实上就连标准错误流都是用的同一个文件项)。一个程序的标准输入输出使用不会产生冲突吗?查看一下当前 shell 的信息:
(py310) xxx ~ $ ls -lh /proc/self/fd/0
lrwx------ 1 xxx xxx 64 May 16 16:49 /proc/self/fd/0 -> /dev/pts/0
(py310) xxx ~ $ ls -lh /proc/$$/fd/0
lrwx------ 1 xxx xxx 64 May 16 16:43 /proc/387/fd/0 -> /dev/pts/0
(py310) xxx ~ $ cat /proc/$$/fdinfo/0
pos: 0
flags: 0100002
mnt_id: 115
ino: 3
(py310) xxx ~ $ cat /proc/$$/fdinfo/1
pos: 0
flags: 0100002
mnt_id: 115
ino: 3
(py310) xxx ~ $ file /proc/$$/fd/0
/proc/387/fd/0: symbolic link to /dev/pts/0
(py310) xxx ~ $ file $(readlink -f /proc/$$/fd/0)
/dev/pts/0: character special (136/0)
- 从两次
ls
可以看出 shell 把和自己关联的文件分给了子进程。 - 从两次
file
看出这个关联文件是一种字符设备。 - 从两次
cat
可以看出字符设备的pos
总是 0,因此文件偏移量不会干扰读写。
学完 62 章终端和 64 章伪终端就明白为什么了。