サブシェルのpidを取得する方法は?
たとえば、
$ echo $$
16808
元のシェルが拡張されているため機能しません$$
。
$ ( echo $$ )
16808
一重引用符が機能しないのはなぜですか?元のシェルから一重引用符を削除した後、サブシェル$$
自体は拡張されませんか?
$ ( echo '$$' )
$$
なぜeval
動作しないのですか?eval
サブシェルによって実行されますか?元のシェルのPIDを提供するのはなぜですか?
$ ( eval echo '$$' )
16808
ありがとうございます。
答え1
$ echo $BASHPID
37152
$ ( echo $BASHPID )
18633
マニュアルから:
BASHPID
現在のbashプロセスのプロセスIDに展開されます。これは
$$
、bashを再初期化する必要がないサブシェルと同じ場合とは異なります。
$
シェルのプロセスIDに展開されます。サブシェルでは、
()
サブシェルではなく現在のシェルのプロセスIDに展開されます。
関連:
答え2
bash
■に加えて、以下を$BASHPID
使用して移植できます。
pid=$(exec sh -c 'echo "$PPID"')
例:
(pid=$(exec sh -c 'echo "$PPID"'); echo "$$ $pid")
これを関数に置き換えることができます。
# usage getpid [varname]
getpid(){
pid=$(exec sh -c 'echo "$PPID"')
test "$1" && eval "$1=\$pid"
}
一部のシェル(たとえば、zsh
またはksh93
)は、を使用して作成されたすべてのサブシェルに対してサブプロセスを開始しません(...)
。この場合と同じになることがあります。これは呼び出しプロセスのPID$pid
なので正しいです。$$
getpid
答え3
Linuxで新しいプロセスを作成しないクロスシェルソリューション(最小のダッシュ、bash、zsh)は次のとおりです。
read -r this_pid < /proc/self/stat; echo ${this_pid%% *}
少なくともbashとzshでは、読取り区切り文字としてスペースを使用することもできます。
read -d ' ' this_pid < /proc/self/stat ; echo $this_pid
また、見ることができます人5プロセス /proc/[pid]/stat セクション
答え4
元の「なぜ」質問に答えるには、$$
サブシェルpidで拡張するか、ゆっくりと評価するのはどうですかeval
?
引用するPOSIX ドキュメント:
$
呼び出しシェルの10進プロセスIDに展開されます。サブシェル(シェル実行環境を参照)では、「$」は現在のシェルと同じ値に拡張する必要があります。