cat < file.txt
ファイルを読む責任は誰にありますか?
シェルはファイルを開いて読み込み、その内容をコマンドの標準入力に書き込みますか?
答え1
シェルコマンドの場合cat <file.txt
:
- リダイレクト演算子を使用
<
すると、シェルが読み取りfile.txt
用に開かれます。 - シェルは
cat
。file.txt
- この
cat
コマンドは、標準入力(sofile.txt
)から内容を読み取り、その内容を標準出力にコピーします。
つまり、ファイルを開くことはシェルであり、cat
データを読み込むことはコマンドです。
シェルとそのサブプロセスで実行されているシステムコールを一覧表示して、何が起こっているのかを確認できます。 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は親シェルプロセス、22703は子プロセスですcat
。)
シェルコマンドはcat file.txt
異なる動作をします。
- シェルは
cat
コマンドを実行し、コマンドに1つの引数を渡しますfile.txt
。 - プログラムが読み取り用に
cat
開きます。file.txt
- この
cat
コマンドはfile.txt
内容を読み取り、標準出力にコピーします。
答え2
あなたは正しいです。ほとんどの場合、これは重要ではありませんが、シェルとプロセスに異なる権限がある場合は問題になる可能性があります。
呼び出すプロセスに昇格された権限(sudo
setuidなど)がある場合は、その権限を使用してシェルで開くことができないファイルを開くことができます。
$ sudo cat < /etc/shadow | wc
-bash: /etc/shadow: Permission denied
0 0 0
$ sudo cat /etc/shadow | wc
64 64 1843