cat < file.txt
谁负责读取文件?
shell 是否读取打开并读取文件,然后将其内容写入命令的标准输入?
答案1
对于 shell 命令cat <file.txt
:
- 重定向运算符
<
导致 shell 打开file.txt
以供读取。 - shell 执行
cat
命令,其标准输入连接到file.txt
. - 该
cat
命令从其标准输入 (sofile.txt
) 读取内容并将内容复制到其标准输出。
因此,shell 是打开文件的人,而cat
命令是读取数据的人。
您可以通过列出 shell 及其子进程执行的系统调用来观察正在发生的情况。在 Linux 上:
$ strace -f sh -c 'cat <file.txt' >/dev/null
execve("/bin/sh", ["sh", "-c", "cat <file.txt"], [/* 76 vars */]) = 0
…
open("file.txt", O_RDONLY) = 3
…
dup2(3, 0) = 0
…
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fbc737539d0) = 22703
[pid 22702] wait4(-1, <unfinished ...>
[pid 22703] execve("/bin/cat", ["cat"], [/* 76 vars */]) = 0
[pid 22703] read(0, "wibble"..., 32768) = 6
[pid 22703] write(1, "wibble"..., 6) = 6
[pid 22703] read(0, "", 32768) = 0
[pid 22703] close(0) = 0
[pid 22703] close(1) = 0
[pid 22703] close(2) = 0
[pid 22703] exit_group(0) = ?
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 22703
--- SIGCHLD (Child exited) @ 0 (0) ---
rt_sigreturn(0x11) = 22703
…
(22702是父shell进程,22703是子进程cat
)
shell 命令的cat file.txt
工作方式有所不同。
- shell 执行该
cat
命令,并向其传递一个参数,即file.txt
. - 该
cat
程序打开file.txt
供阅读。 - 该
cat
命令读取file.txt
内容并将其复制到其标准输出。
答案2
你是对的。虽然这在许多情况下并不重要,但如果 shell 和进程具有不同的权限,那就可以了。
如果您调用的进程具有提升的权限(例如sudo
或 setuid),那么它可以使用这些权限来打开您的 shell 可能无法打开的文件。
$ sudo cat < /etc/shadow | wc
-bash: /etc/shadow: Permission denied
0 0 0
$ sudo cat /etc/shadow | wc
64 64 1843