
プロセス名と 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 0
bash
niceness = 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.*)' 0
(pcre 正規表現構文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
がサポートされていますが、これは正規表現による一致ではなく、バイト単位の正確な等価一致であるため、次のように実行できます。-C
ps
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}'
}