名前とnice番号でプロセスをフィルタリングする

名前とnice番号でプロセスをフィルタリングする

プロセス名と nice 番号のみを使用して PID 番号を見つけるスクリプトを作成しようとしていますが、できません。

答え1

pgrep最初に、最初の引数として指定された式に一致するすべてのプロセスの PID を取得し、次にこれらをループして、2 番目の引数に対応する nice 値を持つプロセスを抽出します。

find_pid_by_name_and_nice () {
    pgrep -- "${1:?missing process name}" |
    xargs -I {} ps -o pid= -o nice= -p {} |
    awk -v nice="${2?missing nice value}" '$NF == nice { print $1 }'
}

テスト:

$ find_pid_by_name_and_nice
find_pid_by_name_and_nice:1: 1: missing process name
find_pid_by_name_and_nice:3: 2: missing nice value
$ find_pid_by_name_and_nice netdata
find_pid_by_name_and_nice:3: 2: missing nice value
$ find_pid_by_name_and_nice netdata 19
258881
258937
$ find_pid_by_name_and_nice netdata 15

(出力なし)

答え2

by_name_and_nice(){ grep -hoPs "^[^ ]+(?= \($1\)( [^ )]+){16} $2 )" /proc/*/stat; }

by_name_and_nice bash 0bashniceness = 0(デフォルト)のすべてのプロセスを検索します。

by_name_and_nice 'b.*' '.*'bは、nice 度などに関わらず、名前が で始まるすべてのプロセスを検索します。

上記に加えて、名前に改行やバイナリ ゴミが含まれるプロセスも取得する場合は、もう少し複雑なものが必要になる場合があります。

by_name_and_nice(){
    local -; set -o pipefail
    LC_ALL=C grep -zhoPs "^[^ ]+(?= \($1\)( [^ )]+){16} $2 )" /proc/*/stat | xargs -0rn1
}

プロセス名に改行文字をマッチさせるには、by_name_and_nice '(?s:foo.*)' 0pcre 正規表現構文GNU grep の-Pオプションで使用されます)。


これはデモ目的のためだけのものです。大なり小なり演算子なしで nice 値で選択しようとするのはまったく意味がありません。また、プロセス名で選択するのはあまり信頼できません。プロセス名はプロセスによって完全に制御されており、2 ビットのマルウェアやクラップウェアによって容赦なく悪用されて、自分自身をpsまたは と呼ぶことがbashできるためです。より良いアイデアは、バイナリのベース名で選択することです。

find /proc/*/exe -lname '*/whatever'

残されたものをすべて開発するのは読者の課題です ;-)

答え3

POSIX では、psおよび を使用しますawk

by_name_and_nice() {
  # returns pids of processes with $2 as niceness and whose
  # process name matches the $1 extended regexp
  ps -A -o pid= -o nice= -o comm= |
    NAME=$1 NICE=$2 awk '
      $2 == ENVIRON["NICE"] {
        pid = $1
        sub(/^[[:space:]]*[^[:space:]]+ +[^[:space:]]+ /, "")
        if ($0 ~ ENVIRON["NAME"]) print pid
      }'
}

これは、niceness 列とプロセス名の間に 1 つのスペース文字があることを前提としています。これは、Linux ベースのシステムによく見られる procps-ng 実装の場合に当てはまりますが、POSIX では保証されていません。niceness 列の後の空白文字をすべて削除することもできますが、名前が空白で始まるプロセスを誤って表現するリスクがあります。

procps-ng はps少なくとも?出力内の非印刷文字を に変更しますが、非印刷文字の構成要素は の呼び出し元のロケールによって決まることに注意してくださいps。たとえば、Stéphane名前が UTF-8 であるプロセスは、ロケールが UTF-8 以外の文字セットを使用しているかのようにレンダリングされる可能性がありますSt??phane

procps-ngただし、の実装では、プロセスを名前で一致させるオプション (HP/UX の からヒントを得たもの)psがサポートされていますが、これは正規表現による一致ではなく、バイト単位の正確な等価一致であるため、次のように実行できます。-Cps

by_name_and_nice() {
  # returns pids of processes with $2 as niceness and whose
  # process name is exactly $1
  ps -C "$1" -o pid= -o nice= |
    awk -v nice="$2" '$2 == nice {print $1}'
}

関連情報