次のコマンドを実行するとき:
exec 3<<< "TEST"
以下が表示されることがわかります/proc
(FD3の読み取りに関する最後の行が削除されました)。
# ls -al /proc/$$/fd
total 0
dr-x------ 2 root root 0 Jan 18 21:09 .
dr-xr-xr-x 9 root root 0 Jan 18 21:09 ..
lrwx------ 1 root root 64 Jan 28 16:22 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 28 16:22 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 18 21:09 2 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 28 16:22 255 -> /dev/pts/0
lr-x------ 1 root root 64 Jan 28 20:42 3 -> /tmp/sh-thd-1123912022914878506 (deleted)
FD 3の内容は一度読み取ることができますが、それ以降は読み取れません。
# cat 0<&3
TEST
# cat 0<&3
# cat 0<&3
私の質問は、/proc/$$/fd/3
すでに「削除済み」と読まれている場合、その内容を読み続けることができる理由についての理論は何ですか?
答え1
ファイル記述子から読み続けることができます。問題は、「dup2」システムコールを使用してファイル記述子への2番目の参照を作成し、ファイル記述子に場所があることです。この位置は最初の猫の後にデータの最後にあります。一度に少しずつデータを読み取ることができます(ここではread
一度に1行ずつ読み込む例を挙げ、通常はread -rを使用します)。場所を元に戻す簡単な方法でPerlを使用しています。ファイルの先頭に。
$ exec 3<<<'This is some text
> and some more
> that is all folks'
$ read <&3 ; echo "$REPLY"
This is some text
$ read <&3 ; echo "$REPLY"
and some more
$ perl -e 'sysseek(stdin,0,0);' <&3
$ read <&3 ; echo "$REPLY"
This is some text
答え2
ファイルを指すディレクトリエントリがもう存在しない場合、ファイルは「削除」されます。この意味でファイルは削除されましたが、ディスクにはまだ存在する可能性があります。これインデックスノードファイルの内容とファイルの内容は、ファイルを閉じるまで削除されません。
ファイルにディレクトリエントリがないと、直接開くことはできません。ただし、既存のディスクリプタはまだファイルにコピーできます。これはリダイレクトです。/proc/PID/fd/FD
システムがクラッシュしてファイルがまだ開いているが削除された場合、データは後で削除されます。次回の起動時にログが再生されるとき、またはFSCKこれを検出するとリンク数0と同じです。
答え3
ファイル記述子を閉じていないため、そのリソースは解放されませんでした。しかし、そのファイル記述子で利用可能なすべての内容を読みました。将来の読み取りはすぐにEOFを取得しますが、ファイル記述子はまだ閉じられていないため、まだ存在します。