回答:
これは(Linuxの下で)実行するはずです:
ps --ppid 2 -p 2 --deselect
kthreadd
(PID 2)はPPID 0を持ちます(Linux 2.6+で)がps
、PPID 0のフィルタリングは許可しません。したがって、この回避策。
kthreadd
、その後に従って構築ps
コールを。このことを「常に」「kthreadd」と呼ぶことはどのくらい保証されますか?安全な解決策はより複雑で、ps
通常どおり実行して出力を解析し、いくつかのテストを実行します。
x
が動作しないフラグのように見えます。ps au --ppid 2 -p 2 --deselect
正常に動作します。
カーネルプロセスを認識する1つの方法は、ユーザーメモリを使用しないため、vszフィールドは0です。これにより、ゾンビも捕捉されます(この観測についてはStephane Chazelasに感謝します)。
ps axl | awk '$7 != 0 && $10 !~ "Z"'
PIDのみをリストするには:
ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
これらのプロセスの特殊性の1つは、実行可能ファイルに裏付けられていないことです。そのため、以下を実行できます(zshで)。
ps /proc/[0-9]*/exe(^-@:h:t)
または、POSIXシェルの場合:
ps -p "$(find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3 | paste -sd , -)"
これは/proc/<pid>/exe
、ファイルへのリンクがあるプロセスのチェックです。
しかし、それは、/proc/<pid>/exe
シンボリックリンクの状態を確認できるようにするには、スーパーユーザーである必要があることを意味します。
編集:たまたまゾンビプロセスは(少なくとも)同じ条件を満たしているので、それらを除外したくない場合は、それらを追加し直す必要があります。のような:
ps -p "$(
{ find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3
ps -Ao pid=,state= | sed -n 's/ Z//p'
} | paste -sd , -)"
なお、ps -f
ショー、それらのプロセス名角括弧ではない彼らだカーネルプロセスなぜなら、彼らは空に持っているので、argv[]
(代わりのPSショープロセス名ので、argv[0]
そこを)。空のユーザー空間プロセスを作成するargv[]
こともできます。また、プロセス名argv[0]
に次の形式を[some-string]
使用することもps
できます。そのため、これらの角かっこに基づいて出力をフィルタリングするのは簡単なオプションではありません。
zsh
構文です。2番目は標準POSIX sh
(and ps
and find
and cut
and paste
)構文です。もちろん/proc
、POSIXでは指定されていません。
wc -l
)。それでは、Hauke Lagingの回答を受け入れて、賛成票を投じます。;)
また、単にps
出力を解析して、括弧内にないプロセス名を探すこともできます。
ps aux | awk '$NF!~/^\[.+\]$/'
awk -F: '$7 ~ home { print $1 }' /etc/passwd
-ただし、そのようなユーザー名に言及するプロセスは引き続き取得され、一時ファイルはそのまま残されます。3番目の解決策が合理的であるという理由だけで、私は下票を撤回します。
$NF
は、ps aux
出力のコマンドラインの最後の単語であることに注意してください。非カーネルプロセスが[...]
存在する場合があります。私の答えで述べたように、[xxx]
表記法はカーネルプロセスであるためではなく、非カーネルプロセスでも許可されるコマンドライン(引数なし)がないためです。
ps
非常に単純化され、出力が異なるbusyboxでこれを試みる人にとっては、Gillesのすばらしい答えのこの変形はうまくいきます:
ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'
Gillesの回答によると、ここでの方法論は、ユーザーメモリを使用しないプロセスを見つけ( `vsz col == 0)、ゾンビプロセスを除外することです(ステータスcolは 'Z'ではありません)。
1ベースのawkフィールド番号がそれに応じて調整される限り、出力列は簡単に調整できます。偽の値を入力することにより、psで使用可能なオプションを確認してください。例えば:
$ ps -o foo
ps: bad -o argument 'foo', supported arguments: user,group,comm,args,pid,ppid,pgid,tty,vsz,stat,rss
カウントのみが必要な場合... カーネルプロセスとユーザープロセスをフィルタリングする同様のニーズがありましたが、それぞれのカウントのみが必要でした。これが私の解決策でした:
ps -eo vsize | awk '{p[$1==0]++} END {printf "%-16s %6d\n%-16s %6d\n%-16s %6d\n", "Kernel processes", p[1], "User processes", p[0], "Total processes", p[0]+p[1]}'
サンプル出力:
Kernel processes 353
User processes 52
Total processes 405
説明:VSZ = 0プロセスがカーネルプロセスであると想定できるというハックを使用しています。でawk
、VSZ(からps -eo vsize
)の比較を、ゼロに等しいかどうかを評価します。比較の結果は0または1のブール値になります。配列を作成し、p[]
プロセスのリストを実行しながら、それがカーネルプロセスである場合、増分しますp[1]++
。それ以外の場合、ユーザープロセスとしてをインクリメントしますp[0]++
。すべての増分の後、END { }
ブロック内のp [0]およびp [1]の値(つまり、カウント)にラベルを付けて印刷します。
あなたは私の友人、探しているもの、ではないps
、しかしpstree
。
最初に、最初のカーネルプロセスを特定します。通常、PIDはsystemdのないシステムでは1、systemdのある2です。
次に、次のコマンドを使用します。
$ pstree -p <1 or 2> | grep -o '([0-9]\+)' | grep -o '[0-9]\+'
選択した回答((の付いたもの)は別のコマンドを使用しています:
$ ps --ppid 2 -p 2 --deselect
このps
コマンドの問題は、直接の子のみが含まれ、すべての子孫が含まれないことです。pstree
コマンドは、すべての子孫が含まれます。これら2つのコマンドの出力を比較およびカウント(簡単な方法を使用| wc
)して確認できます。
kthreadd
が常にPID 2 であることはどの程度保証されていますか?