走りながら気づいた
ls /proc/self/fd
次の結果が表示されます。
0 1 2 3 47
明らかに、および0
は1
それぞれ、およびの記述子であり、2
ディレクトリにアクセスするために使用される記述子です。stdin
stdout
stderr
3
ls
しかし、何ですか47
?実行中の出力は次のls
とおりです(特定の項目ではなく)、シェルから渡された項目でなければなりません。cat
$ cat /proc/self/fd/47
cat: /proc/self/fd/47: Permission denied
# example of running cat on a non-existent file descriptor
$ cat /proc/self/fd/46
cat: /proc/self/fd/46: No such file or directory
ls -l
に接続されているそうですanon_inode:inotify
。
私はKDEでArch Linuxを使用していますが、ttyでコマンドを実行するとこれが起こらないようです。端末に固有のものもありますが(私はKonsoleを使用しています)、シェルには固有ではありません(とその両方で発生しますbash
)。zsh
とにかく、シェルはexecの前に0-2を除くすべての記述子を閉じるべきではありませんか(またはそのようにマークする必要がありますO_CLOEXEC
)?
私はKDEプラズマ5.27.10を実行しています。
編集:sudo
0-2を除くすべてのディスクリプタを閉じた状態でテストした結果、sudo konsole
この新しいターミナル内のインスタンスはディスクリプタを新しいプロセスにzsh
流出しません。これは、Konsole自体には何の問題もありませんが、47
親から記述子plasmashell
を受け取っていることを意味します。
答え1
FD 47には特別なものはありません。少なくとも基準はありません。
ファイル記述子を開くと、他のプログラムに対してexec()を呼び出すときにファイル記述子を閉じる必要があるかどうかを示すフラグを設定できます。ほとんどのプログラムは、最初の3つ(時には4つ)以上の開かれたファイル記述子を無視するため、ファイルが開いていてexecで開いた状態で表示されている場合は、いくつかの手順を実行できます。プログラムは開いたままです。誤って開いた可能性が高いです。これはファイル記述子の漏れエラーです。開いているアイテムを追跡するのは難しいかもしれません。特に、開いている項目が実行されなくなる可能性があることを考慮すると、さらにそうです。
一部のシェルは、初期化中にクリーンアップするためにすべての外部オープンファイル記述子を慎重に閉じるため、端末のシェルで開かれたものを見ることができません。誤ってファイル記述子を漏洩することは、漏洩したFDが誤って他のプログラムに漏洩する可能性があるデータを渡す可能性があるため、セキュリティの脆弱性になる可能性があります。
これはユーザーを変更するときに特に危険であるため、追加の項目をsudoすることをお勧めします。