
我正在嘗試建立腳本來查找僅包含進程名稱和好編號的 PID 編號,但我無法做到。
答案1
用於pgrep
首先取得與第一個參數給出的表達式相符的所有進程的 PID,然後循環遍歷這些進程以提取具有與第二個參數相對應的良好值的進程。
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.*' '.*'
將找到名稱以 a 開頭的所有進程b
,無論它們的好壞,依此類推。
如果您還想在名稱中獲取帶有換行符和二進制垃圾的進程,您可能需要一些更複雜的東西:
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
選項使用)。
這僅用於演示目的;在沒有大於或小於運算符的情況下嘗試按良好值進行選擇是毫無意義的。另外,透過進程名稱進行選擇也不是很可靠,因為進程名稱處於進程的完全控制之下,任何兩位惡意軟體和垃圾軟體都會無情地濫用進程名稱來稱呼自己ps
或bash
.更好的想法是透過二進位檔案的基本名稱進行選擇,如下所示
find /proc/*/exe -lname '*/whatever'
發展所有剩餘的內容作為讀者的練習;-)
答案3
POSIXly,使用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
}'
}
假設友善列和進程名稱之間有一個空格字元。這恰好是 procps-ng 實現的情況,通常在基於 Linux 的系統上發現,但 POSIX 不保證。您可以刪除 Niceness 列後的所有空格字符,但這存在錯誤表示名稱以空格開頭的進程的風險。
請注意,procps-ngps
至少將?
輸出中的不可列印字元變更為不可列印字符,且不可列印字元的構成取決於 呼叫者的區域設定ps
。例如,Stéphane
名稱為 UTF-8 的程序可能會呈現為好像St??phane
語言環境使用與 UTF-8 不同的字元集。
procps-ng
的實現確實ps
支持一個-C
選項來匹配名稱上的進程(受到 HP/UX' 的啟發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}'
}