2

Unix システムで面白い問題に遭遇しました (SunOS および AIX でテスト済み): スクリプトを実行し、それ自体を一覧表示したい ( を使用ps) - ps がスクリプトの追加の子プロセスを 2 つ表示する場合もあれば、追加の子プロセスを 1 つだけ表示する場合もありますほとんどの場合、出力には単一のプロセスが正しく表示されます。ここでスレッドを見つけました同じ名前の複数のプロセスですが、私の場合は異なります。

test.sh次のような名前のスクリプトを考えてみましょう。

#!/bin/ksh
echo before $$
ps -f | grep test.sh | grep -v grep
echo after $$

それは非常に簡単です-PIDを表示し、プロセスリストでそれ自体(およびそのようなもの)を見つけ、grepコマンドのみを除外します(念のため)。ここで、シェルで非常に単純なルーチンを実行します。

while [ 1 -eq 1 ]; do test.sh; done

test.sh1つずつ実行するだけの無限ループ。出力には何が得られますか? 下記参照:

before 20990
  user   20990 14993   0 08:54:06 pts/5       0:00 /bin/ksh test.sh
after 20990
before 20994
  user   20994 14993   0 08:54:06 pts/5       0:00 /bin/ksh test.sh
after 20994
before 20998
  user   21001 20998   0 08:54:06 pts/5       0:00 /bin/ksh test.sh
  user   21000 20998   0 08:54:06 pts/5       0:00 /bin/ksh test.sh
  user   20998 14993   0 08:54:06 pts/5       0:00 /bin/ksh test.sh
after 20998
before 21002
  user   21002 14993   0 08:54:06 pts/5       0:00 /bin/ksh test.sh
after 21002
before 21006
  user   21006 14993   0 08:54:07 pts/5       0:00 /bin/ksh test.sh
after 21006

プロセス 21001 と 21000 とは何か説明してもらえますか? 「前/後」の痕跡がないため、フォークされません。これはたまにしか起こりません...

これは私にとって大した問題ではありませんが、ここで何が起こっているのか、より複雑なケースでは何が予想されるのか知りたいです。

このスクリプトの他のセッションが実行されていない場合にのみ、スクリプトの実行を許可したいとしましょう。次に、ps を使用して "test.sh" をフィルター処理し、PID を使用してすべての行をフィルター処理します。ここでは、スクリプトはそれ自体とその子をフィルター処理します。本当にわかりません。したがって、このスレッド:)

Sun や AIX のファイルシステムの構造がわからないので、/proc に格納されている実際のデータをフェッチすることはしませんでした。

4

1 に答える 1

1

これらの追加プロセスは、最初の 2 つのパイプライン コンポーネントを処理しようとしているサブシェルです。

これは、すべての exec 呼び出しを表示する dtrace スクリプトを実行して確認されます。

before 3929
    root  3929  1630   0 10:36:03 pts/3       0:00 /bin/ksh ./test.sh
    root  3932  3929   0 10:36:03 pts/3       0:00 /bin/ksh ./test.sh
    root  3931  3929   0 10:36:03 pts/3       0:00 /bin/ksh ./test.sh
after 3929

これらのプロセスの dtrace 出力:

2013 Sep  5 10:36:02 3929 /bin/ksh ./test.sh
2013 Sep  5 10:36:02 3931 grep test.sh
2013 Sep  5 10:36:02 3932 grep -v grep

/bin/ksh ./test.sh実際のコマンド実行の代わりに表示される事実は、まだargv[0]更新されていません。これは、exec 呼び出しが完了した後にのみ置き換えられます。

fork の直後、親プロセスと子プロセスの両方が同じ引数リストを共有します。唯一の違いはプロセス ID です。これはあなたが観察しているものです。

于 2013-09-05T08:31:10.353 に答える