psコマンドがプロセス全体のリストを表示しないのはなぜですか?

psコマンドがプロセス全体のリストを表示しないのはなぜですか?

このコマンドを実行すると、ps awx | grep -v grep次の出力が生成されます。次のリストは、出力全体の最後の20行です。

 4247 pts/1    Ss+    0:00 /bin/bash
 4442 ?        S<     0:00 [kworker/u17:1]
 4661 ?        S<     0:00 [kworker/u17:3]
 4731 ?        S<     0:00 [kworker/u17:5]
 4734 ?        S      0:00 pickup -l -t fifo -u
 4847 ?        S<     0:00 [kworker/u17:7]
 4850 ?        S      0:00 [kworker/u16:3]
 4878 ?        S      0:00 [kworker/u16:0]
 5201 ?        S<     0:00 [kworker/u17:8]
 5353 ?        S      0:00 [kworker/0:1]
 5354 ?        S      0:00 [kworker/7:2]
 5355 ?        S      0:00 [kworker/u16:2]
 5361 ?        S      0:00 [kworker/4:0]
 5362 tty1     Ss     0:00 -bash
 5396 ?        S      0:00 [kworker/6:0]
 5418 ?        S      0:00 [kworker/0:0]
 5420 ?        S      0:00 [kworker/2:2]
 5431 ?        S      0:00 [kworker/7:0]
 5562 ?        S      0:00 [kworker/4:2]
 5620 tty1     R+     0:00 ps awx

ps awx | grep grep後続のコマンドを実行すると、次の出力が生成されます。

5646 tty1     S+     0:00 grep --color=auto grep

また、次のコマンドを実行すると、次のps awx | grep agetty出力が表示されます。

5669 tty1     S+     0:00 grep --color=auto agetty

コマンドがps awxプロセス識別番号5646と5669を表示しないのはなぜですか?実際、5620以降は他のプロセスはリストされません。

答え1

ps awxコマンドがプロセス識別番号5646と5669を表示しないのはなぜですか?

なぜなら、あなたはただ5646注文の一部としてps awx | grep grep、そして注文の一部と5669して始めたからです。ps awx | grep agetty最初のリストの後に始まるので、リストには表示されません。どちらもその特定のパイプのプロセスへの入力が処理されるまで実行されるため、将来のpsリストには表示されません。

同様psに繰り返し実行すると、プロセスIDが変更されていることがわかります。コマンドを実行するたびに新しいプロセスが開始されます。


より具体的には、問題の2番目のプロセスは次のとおりです。

5669 tty1     S+     0:00 grep --color=auto agetty

これにはパラメータとがすでにgrep提供されています。これはのコマンドと一致し、フラグはエイリアスから来ることができます。これはプロセスではありません。そのうちの1つは、Debianシステムのこの例のように、コマンドラインの最初の部分として、またはを持つことができます。--color=autoagettygrepps awx | grep agetty--color=autoagettyagetty/sbin/agetty

1269 tty3     Ss+    0:00 /sbin/agetty --noclear tty3 linux

答え2

fork()プロセスはカーネルの内側と外側の両方からカーネルを通ってマイクロ秒単位で入って行くことができます。実際に引用してみるとマイケル・ポカラキス:

PIDがユーザー空間で誤った順序で表示されるのは、カーネルスケジューリングがfork()呼び出し間でプロセスを分岐する可能性があるためです。実際、これは非常に一般的です。

それで、その間に多くのことがps awx | grep -v grep起こりましたps awx | grep grep。新しいプロセスとスレッドがあります。ps捕捉される前に終了します。最後の例でも同じロジックが発生しますps awx | grep grep。しかし、grepPIDは実際には最新ではないかもしれません。 関連回答のGilles指摘した:

[p]ipedコマンドが同時に実行されます。 ps | grep ...を実行するときにpsまたはgrepが最初に開始されるかどうかは運の問題です(またはシェル操作の詳細とカーネル内部スケジューラの微調整の問題)。とにかく彼らは続く。

また、そのgrep -v grep目的はps出力から自分自身を削除することです(| grep -v [g]repこの場合は実際に推奨されることが多いです)。関連投稿)。

関連情報