psはLinux上の非カーネルプロセスのみを表示できますか?


41

psカーネルスレッドではなく、ユーザープロセスのみを表示するように要求するにはどうすればよいですか?

参照してくださいこの質問を私が何を意味するか見るために...

回答:


37

これは(Linuxの下で)実行するはずです:

ps --ppid 2 -p 2 --deselect

kthreadd(PID 2)はPPID 0を持ちます(Linux 2.6+で)がps、PPID 0のフィルタリングは許可しません。したがって、この回避策。


いいですが、それkthreaddが常にPID 2 であることはどの程度保証されていますか?
l0b0

@ l0b0私は考えている:-)あなたは二段階でこれを行うことができます:のPIDを決定しkthreadd、その後に従って構築psコールを。このことを「常に」「kthreadd」と呼ぶことはどのくらい保証されますか?安全な解決策はより複雑で、ps通常どおり実行して出力を解析し、いくつかのテストを実行します。
Hauke Laging

2
少なくともx86アーキテクチャ上のLinux 2.4では、これらのプロセスにはppid 1があったため、そのように区別することはできませんでした。
ステファンシャゼラス

1
「ps -ef」のように「ps --ppid 2 -p 2 --deselect -f」を行い、「ps aux」のように「ps --ppid 2 -p 2 --deselect u」を行う
Peter

1
@Totor私はチェックしましたが、これxが動作しないフラグのように見えます。ps au --ppid 2 -p 2 --deselect正常に動作します。
Sankalp

9

カーネルプロセスを認識する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
@StephaneChazelas良い点、フィルターに条件を追加しました。
ジル 'SO-悪であるのをやめる'

9

実際には、次のイディオムが十分に見つかりました。

ps auxf | grep -v ]$

角括弧で終わる行をフィルタリングします。これにより、不要なエントリが省略される可能性がありますが、ほとんどありません。それと引き換えに、覚えやすく、入力も比較的簡単です。

avahi-daemonなどの一部のプロセスは、括弧内のプロセス名情報(avahi-daemonの場合はホスト名)に追加され、このコマンドによって除外されます。


8

これらのプロセスの特殊性の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できます。そのため、これらの角かっこに基づいて出力をフィルタリングするのは簡単なオプションではありません。


これは非標準のシェル構文です。
トーター

1
@Totor、私が言ったように、最初のものはzsh構文です。2番目は標準POSIX sh(and psand findand cutand paste)構文です。もちろん/proc、POSIXでは指定されていません。
ステファンシャゼラス

普遍的であるため、この回答を受け入れます(編集ありがとう)。ただし、Hauke Lagingの答えは、2.4カーネルを扱っていない限り、非常に素晴らしく簡単です。
トーター

@ Totor、Haukeの答えには、スーパーユーザーの特権を必要としないという利点もあります。私の答えは2.4および2.6 / 3カーネルで動作しますが、とにかく4.xで動作することを保証するものではないと思います。
ステファンシャゼラス

うーん、あなたは正しい、私はルート権限について考えていませんでした。ルートでない場合でも答えが得られるため、間違いを招く可能性がありますが、違います(たとえば、で数える場合は注意が必要ですwc -l)。それでは、Hauke Lagingの回答を受け入れて、賛成票を投じます。;)
Totor

1

また、単にps出力を解析して、括弧内にないプロセス名を探すこともできます。

ps aux | awk '$NF!~/^\[.+\]$/'

興味のあるユーザーのリストを取得するためのやや信頼性の低い方法:awk -F: '$7 ~ home { print $1 }' /etc/passwd-ただし、そのようなユーザー名に言及するプロセスは引き続き取得され、一時ファイルはそのまま残されます。3番目の解決策が合理的であるという理由だけで、私は下票を撤回します。
キーストンプソン

ああ、あなたはずっと正しいです、@ KeithThompson、他の人を削除しました、彼らは価値がありません。(現在の)廃止されたコメントを整理するのを手伝ってもらえますか?
テルドン

2
これ$NFは、ps aux出力のコマンドラインの最後の単語であることに注意してください。非カーネルプロセスが[...]存在する場合があります。私の答えで述べたように、[xxx]表記法はカーネルプロセスであるためではなく、非カーネルプロセスでも許可されるコマンドライン(引数なし)がないためです。
ステファンシャゼラス

1

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

0

カウントのみが必要な場合... カーネルプロセスとユーザープロセスをフィルタリングする同様のニーズがありましたが、それぞれのカウントのみが必要でした。これが私の解決策でした:

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]の値(つまり、カウント)にラベルを付けて印刷します。


0

あなたは私の友人、探しているもの、ではない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)して確認できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.