私はbashプロセスについてよく知りませんが、パイプとtee
。
以下では、スクリプトパスがで置き換えられます$FOLDER
。
$FOLDER/DBB/myparent.ksh
:echo "BEGIN $$ this is the parent process" $FOLDER/DBB/myChild.ksh echo "END $$ this is the parent process"
$FOLDER/DBB/mychild.ksh
:function toto { echo " this is $$ child process " sleep 10 } { echo " $$ go1 " toto ptree $$ echo " $$ go2 " } | tee myLog$$.log
を起動すると、
myParent.ksh
次のプロセスツリーが表示されます。28417 /usr/lib/ssh/sshd -R 28531 -ksh 41387 /bin/bash myParent.ksh 41390 /bin/bash $FOLDER/DBB/myChild.ksh 41391 /bin/bash $FOLDER/DBB/myChild.ksh 41393 sleep 10 41392 tee myLog41390.log
コンソール出力:
BEGIN 52665 this is the parent process in myChild.ksh 52680 go1 this is 52680 child process 20192 zsched 21104 /usr/lib/ssh/sshd 27882 /usr/lib/ssh/sshd -R 28417 /usr/lib/ssh/sshd -R 28531 -ksh 52665 /bin/bash myParent.ksh 52680 /bin/bash $FOLDER/DBB/myChild.ksh 52688 /bin/bash $FOLDER/DBB/myChild.ksh 61896 ptree 52680 52692 tee myLog52680.log 52680 go2 END 52665 this is the parent process
なぜ2つですか$FOLDER/DBB/myChild.ksh
?
答え1
シェルスクリプトにはサフィックスが付いていますが、プロセスツリーは.ksh
そのスクリプトが実際にbash
シェルによって実行されることを示します。
私のDebian 11 man ksh
(実際にはmksh
MirBSD Kornシェル)では、次のように言います。
パイプ内のすべてのコマンドは別々のサブシェルで実行されます。これはPOSIXでは許可されていますが、最後のコマンドを除くすべてのコマンドは、サブシェルで実行されるAT&T UNIX kshの2つのバリエーションとは異なります。意味と解決策のための機能です。
そしてman bash
言った:
パイプラインの各コマンドは、別々のプロセス(つまりサブシェルで)で実行されます。 [...]
lastpipe
組み込み機能を使用してこのオプションを有効にするとshopt
(以下の説明を参照shopt
)、パイプの最後の要素がシェルプロセスによって実行される可能性があります。
したがって、最初にプロセス#41390が実行を開始するプロセスですmyChild.ksh
。パイプが見えるとき:
{
echo " $$ go1 "
toto
ptree $$
echo " $$ go2 "
} | tee myLog$$.log
$$
パイプを展開し、{
#41391の複合コマンドのサブシェルプロセスをフォークします}
。
プロセス#41392は、内部ではなくコマンドを実行し、それを最適化として処理する必要があるサブシェルであっても、親exec()
プロセス#41390によってtee
直接fork()
コマンド+ 'd'になってもよい。exec()
どちらの場合も、同じ結果をもたらします。 #41392は、表示されているコマンドラインを変更するexec()
操作を実行します。exec()
ptree
一方、サブシェル#41391には複数のコマンドが実行されるため、プロセス#41391はサブシェルとしてのアイデンティティを維持します。実行する必要がある最後のコマンドはecho
シェル内部コマンドであるため、サブシェルプロセスとしての寿命は終了します。そして、パイプライン実行を準備するとき、親#41390はすでに$$
sを拡張しているため、サブシェル#41391のPIDは出力に表示されません。