/ proc / selfは構文糖衣です。これは、/ proc /とgetpid()syscallの結果(メタ変数$$としてbashでアクセス可能)の汚染へのショートカットです。シェルスクリプトの場合、多くのステートメントが他のプロセスを呼び出し、独自のPIDで完了しているため、混乱する可能性があります...デッドプロセスを参照するPID。考慮してください:
root@vps01:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 Jan 1 01:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jan 1 01:51 3 -> /proc/26562/fd
root@vps01:~# echo $$
593
'/ bin / ls'はディレクトリへのパスを評価し、/ proc / 26563として解決します。これは、ディレクトリの内容を読み取るプロセス(新しく作成された/ bin / lsプロセス)のPIDであるためです。しかし、パイプラインの次のプロセス、シェルスクリプトの場合、またはプロンプトが戻ってくるまで、インタラクティブシェルの場合、パスは存在しなくなり、情報出力は存在しないプロセスを参照します。
ただし、これは外部コマンド(シェル自体に組み込まれるのではなく、実際の実行可能プログラムファイルであるコマンド)にのみ適用されます。したがって、たとえば、ファイル名グロビングを使用してディレクトリの内容のリストを取得すると、パス名を外部プロセス/ bin / lsに渡すのではなく、異なる結果が得られます。
root@vps01:~# ls /proc/self/fd
0 1 2 3
root@vps01:~/specs# echo /proc/self/fd/*
/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
最初の行では、シェルはexec()syscallを介してargv [1]として「/ proc / self / fd」を渡し、新しいプロセス「/ bin / ls」を生成しました。「/ bin / ls」は、ディレクトリ/ proc / self / fdを開いて、その内容を繰り返して読み取った後、印刷しました。
ただし、2行目では、舞台裏でglob()を使用してファイル名のリストを展開しています。これらはエコーする文字列の配列として渡されます。(通常は内部コマンドとして実装されますが、多くの場合/ bin / echoバイナリもあります...しかし、エコーは文字列のみを処理するため、実際にはその部分は無関係です。
ここで、次の場合を考えます。
root@vps01:~# cd /proc/self/fd
root@vps01:~# ls
0 1 2 255
ここでは、 / bin / ls の親プロセスであるシェルが、/ proc / selfのサブディレクトリを現在のディレクトリにしています。したがって、相対パス名はその観点から評価されます。私の最良の推測は、これが、開いているファイル記述子を含む、ファイルへの複数のハードリンクを作成できるPOSIXファイルセマンティクスに関連していることです。したがって、今回は、/ bin / lsはecho / proc / $$ / fd / *と同様に動作します。
/proc/self
もちろん、評価するプロセス。