pgrep 指令:依名稱找 PID、-f 選項,以及 pidof 與 pkill 的差異
要依名稱、帳號或命令列找出執行中程序的編號(PID),就使用 pgrep 指令。我們在 AlmaLinux 9 伺服器上把 sleep 程式複製成其他名稱,啟動三個程序,再比較各選項找到的程序。依名稱找只出現這三個程序,用 -f 在整個命令列中找時,連啟動它們的 timeout 也一起出現。
下方輸出是在 AlmaLinux 9.8 伺服器的 root 帳號與 Debian 12 伺服器的一般帳號上執行的結果。要找的對象是把 sleep 複製成 pgdemo-a、pgdemo-b 這兩個名稱,再用 timeout 300 啟動的程序,讓它們 5 分鐘後自行結束。程序編號(PID)和 Debian 帳號名稱(user1)已換成範例值,AlmaLinux 伺服器的 procps-ng 版本號只寫到主版本與次版本。
1️⃣ pgrep 指令基本用法
在 pgrep 後面寫上名稱的一部分,就會把名稱含有這些字元的程序編號一行一個輸出。用 pgdemo 找時出現了兩個 pgdemo-a 和一個 pgdemo-b,共三個編號。
pgrep pgdemo2143
2152
2155把名稱寫到 pgdemo-a 時,只剩下兩個 pgdemo-a。
pgrep pgdemo-a2143
2152要找的字串以延伸正規表示式讀取,沒有選項時只在程序名稱中找。
找不到符合的程序時不會輸出任何東西就結束,所以要用結束代碼確認結果。找了不存在的名稱 pgdemo-zz 後執行 [echo $?],得到 1。
pgrep pgdemo-zzecho $?1不寫任何條件就執行時,出現下方錯誤和結束代碼 2。man 頁面把結束代碼說明為 0(找到)、1(找不到)、2(命令列語法錯誤)、3(記憶體不足等嚴重錯誤)。
pgreppgrep: no matching criteria specified
Try `pgrep --help' for more information.echo $?2把這個結束代碼當作條件而不是看輸出,腳本就能確認程序是否在執行。版本用 [pgrep -V] 確認。Debian 12 伺服器是 procps-ng 4.0.2,AlmaLinux 9.8 伺服器是 procps-ng 3.3。
pgrep -Vpgrep from procps-ng 4.0.22️⃣ pgrep -f 選項與 -l、-a 輸出
只看編號無法知道是哪個程序,所以用 -l 一起輸出名稱,用 -a 一起輸出整個命令列。
pgrep -l pgdemo2143 pgdemo-a
2152 pgdemo-a
2155 pgdemo-bpgrep -a pgdemo2143 ./pgdemo-a 300
2152 ./pgdemo-a 301
2155 ./pgdemo-b 300-a 輸出最後的 300 和 301 是傳給 sleep 的秒數引數。我們用這個引數區分了兩個同名的 pgdemo-a。
加上 -f 就不是在名稱中找,而是在整個命令列中找。用 -f 找 pgdemo-a 時,編號從兩個增加到四個。
pgrep -f pgdemo-a2141
2143
2150
2152再加上 -a 一看,多出來的兩行是以 pgdemo-a 為引數執行的 timeout。它們的名稱是 timeout,但命令列中含有 pgdemo-a,所以符合 -f 的條件。
pgrep -af pgdemo-a2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 301在腳本中使用 -f 時,要確認腳本本身會不會出現在結果中。pgrep 不會把執行中的自己放進結果,但如果執行 pgrep 的腳本命令列中有要找的字串,那個腳本也會出現在結果中。
用把收到的字串直接交給 [pgrep -af] 的腳本 chk.sh 找 pgdemo-a 時,最後一行多了腳本本身 bash chk.sh pgdemo-a。
bash chk.sh pgdemo-a2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 301
2160 bash chk.sh pgdemo-a用方括號把第一個字母括起來的 [p]gdemo-a,以正規表示式來說會找和 pgdemo-a 相同的字串,但腳本命令列中連方括號都原樣寫著,所以不符合條件。把這個模式交給同一個腳本後,腳本那一行消失,只剩四行。
bash chk.sh '[p]gdemo-a'2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 3013️⃣ pgrep 條件選項
加上 -x 就只找名稱完全相同的程序,而不是名稱的一部分。用 pgdemo 什麼都沒找到,用 pgdemo-a 找到兩個。
pgrep -x pgdemopgrep -lx pgdemo-a2143 pgdemo-a
2152 pgdemo-a-u 依執行程序的帳號篩選。用逗號寫多個帳號時,會找出屬於其中任一帳號的所有程序。以 root 執行的三個程序用 [-u root] 全部出現,用 [-u daemon] 一個也沒有。
pgrep -u root -l pgdemo2143 pgdemo-a
2152 pgdemo-a
2155 pgdemo-bpgrep -u daemon -l pgdemopgrep -u root,daemon -c pgdemo3寫了不存在的帳號時,出現 [invalid user name] 錯誤和結束代碼 2。
pgrep -u no-such-user9 pgdemopgrep: invalid user name: no-such-user9在 Debian 12 伺服器的一般帳號上,也用相同選項找到了以自己帳號啟動的一個 sleep。
pgrep -u user1 -l sleep3047 sleeppgrep -u user1 -a sleep3047 sleep 60同名的程序有多個時,-n 只輸出最近啟動的一個,-o 只輸出最早啟動的一個。在間隔 2 秒啟動的兩個 pgdemo-a 中,-n 選了後啟動的,-o 選了先啟動的。
pgrep -n pgdemo-a2152pgrep -o pgdemo-a2143man 頁面說明 -n 和 -o 不能同時使用。兩個一起寫時,沒有錯誤訊息,只出現用法說明。
-c 輸出個數而不是編號。找不到時輸出 0,結束代碼是 1。
pgrep -c pgdemo3pgrep -c pgdemo-zz0pgrep 選項整理如下。
| 選項 | 複製 | 說明 |
|---|---|---|
| -f--full | 不在名稱而在整個命令列中找 | |
| -l--list-name | 編號連同名稱一起輸出 | |
| -a--list-full | 編號連同整個命令列一起輸出 | |
| -x--exact | 只找名稱完全相同的程序 | |
| -u--euid | 只找指定帳號執行的程序,用逗號寫多個時為其中任一帳號 | |
| -n--newest | 符合條件中最近啟動的一個 | |
| -o--oldest | 符合條件中最早啟動的一個 | |
| -c--count | 輸出個數而不是編號,0 個時結束代碼為 1 | |
| -d--delimiter | 指定編號之間的分隔字元(預設為換行) | |
| -V--version | 輸出版本 |
| 選項 | 複製 | 說明 |
|---|---|---|
| -i--ignore-case | 不分大小寫地找 | |
| -v--inverse | 找出不符合條件的程序 | |
| -P--parent | 只找指定父程序編號(PPID)的子程序 | |
| -t--terminal | 只找連接到指定終端機的程序 | |
| -g--pgroup | 只找屬於指定程序群組編號的程序 | |
| -s--session | 只找屬於指定工作階段編號的程序 | |
| -U--uid | 只找真實使用者 ID 相同的程序 | |
| -G--group | 只找真實群組 ID 相同的程序 | |
| -w--lightweight | 輸出所有執行緒編號而不是程序編號 |
🔲 pgrep 指令模擬器
下方模擬器從 pgdemo 與 timeout 六行再加上範例程序的清單開始。點選按鈕可在左側清單比較各選項找到的行,也能在 [pkill pgdemo-b] 之後用 [pgrep -l pgdemo] 確認結果變少。
4️⃣ pgrep 與 pidof、pkill 的差異
pidof 不用正規表示式,只找程式名稱完全相同的程序,並把編號以空格隔開輸出在同一行。找 pgdemo-a 時兩個編號出現在同一行,後啟動的 2152 排在前面。
pidof pgdemo-a2152 2143用名稱的一部分 pgdemo 時,和 pgrep 不同,什麼都沒找到,結束代碼是 1。只需要一個編號時加上 -s。[pidof -s pgdemo-a] 只輸出了 2152。
pidof pgdemopidof -s pgdemo-a2152若要用找到的編號查看啟動時間與父程序編號(PPID),就用 pgrep -d 以逗號串起編號,再交給 ps 指令的 -p。
pgrep -d, pgdemo2143,2152,2155ps -fp $(pgrep -d, -x pgdemo-a)UID PID PPID C STIME TTY TIME CMD
root 2143 2141 0 15:59 ? 00:00:00 ./pgdemo-a 300
root 2152 2150 0 15:59 ? 00:00:00 ./pgdemo-a 301PPID 欄的 2141 和 2150 是執行兩個 pgdemo-a 的 timeout 的編號。
pkill 用與 pgrep 相同的條件找程序,但不輸出編號,而是送出訊號。不寫訊號時送出 SIGTERM,也可以像 [pkill -HUP 名稱] 這樣換成其他訊號。
pkill 一找到就立刻送出訊號,所以要先用相同條件的 [pgrep -a] 或 [pgrep -af] 確認對象。用 -f 找時,命令列中含有相同字串的 timeout 或腳本也會成為對象。如果已經知道編號,就用 kill 指令只對該編號送出訊號。
| 指令 | 尋找依據 | 輸出 | 作用 |
|---|---|---|---|
| pgrep | 名稱的一部分(正規表示式)、-f 時為整個命令列 | 編號,用 -l、-a 加上名稱與命令列 | 只找 |
| pidof | 完整的程式名稱 | 編號寫在同一行 | 只找 |
| pkill | 與 pgrep 相同的條件 | 無 | 對找到的程序送出訊號(預設 SIGTERM) |
🔢 FAQ & 推薦內容
ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。