為什麼“pgrep firefox”不能在 Ubuntu 20.04 上執行
正如標題所示,Ubuntu 20.04 上的以下命令:
pgrep firefox
… 不返回任何結果。
同時,以下命令:
ps aux |grep firefox
… 返回 6 個結果,其中 5 個應該匹配
pgrep firefox
。pgrep
Ubuntu 上的原始命令有什麼問題?ubuntu 81646 1.9 7.9 3063696 300208 ? Sl 13:12 0:29 /usr/lib/firefox/firefox -new-window ubuntu 81891 0.2 3.8 2473448 144796 ? Sl 13:12 0:03 /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -prefsLen 1 -prefMapSize 222536 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 81646 true tab ubuntu 82020 0.1 3.7 2438972 141396 ? Sl 13:12 0:02 /usr/lib/firefox/firefox -contentproc -childID 3 -isForBrowser -prefsLen 897 -prefMapSize 222536 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 81646 true tab ubuntu 82051 0.0 2.8 2401248 107520 ? Sl 13:12 0:01 /usr/lib/firefox/firefox -contentproc -childID 4 -isForBrowser -prefsLen 6935 -prefMapSize 222536 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 81646 true tab ubuntu 83658 0.0 2.0 2387704 78496 ? Sl 13:12 0:00 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 10362 -prefMapSize 222536 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 81646 true tab ubuntu 90700 0.0 0.0 17664 664 pts/0 S+ 13:37 0:00 grep --color=auto firefox
在 Ubuntu 18.04 和 macOS 上執行相同的命令效果很好。
為什麼
pgrep firefox
在 Ubuntu 20.04 上不起作用因為這是一個錯誤: https ://bugzilla.mozilla.org/show_bug.cgi?id=1649010 。
一種解決方法是:
pgrep "firefox|MainThread"
為什麼這行得通?
- 當 Ubuntu 上的 Firefox 79 執行時,它會寫入值
MainThread
to/proc/<pid>/comm
(感謝 @steeldriver 在上面的評論/問題部分指出這一點)pgrep
然後使用來自/proc/<pid>/comm
, 的值來查找匹配命令|
管道分隔符允許pgrep
匹配多個值。建議保留firefox
ANDMainThread
以便此命令在舊版本(例如 Ubuntu 18.04 + Firefox 78)上pgrep firefox
仍然可以正常執行。為什麼這可能不准確?
- 警告
MainThread
:程序名稱不是 firefox的任何程序也將報告為使用此技術執行。謹慎使用。- 警告:多個程序可能處於活動狀態。請參閱此答案以找出原因:https ://unix.stackexchange.com/a/607242/190347
- 注意
pgrep -x "firefox|MainThread"
:建議進行完全匹配我們還有哪些其他選擇?
- 正如@steeldriver 指出的那樣,可以推斷出這
pgrep -f firefox
是一個合適的替代品。它的命運與MainThread
它可能匹配其中包含firefox
的命令(例如目錄名、文件名等)的情況相似。出於這個原因,我發現它更有可能匹配流氓程序——因此更有可能拋出誤報——而不是MainThread
字元串。這是基於經驗的預感,沒有書面證據,但是在 GitHub 上的快速搜尋顯示這MainThread
不是一個常見的項目名稱(58 個結果,而不是firefox
匹配的 21,000 個儲存庫)- 或者,使用命令/技術的組合來過濾掉誤報可能比所有其他命令更受歡迎(例如從兩個命令中查找結果的聯合)
- 問。在直接詢問 Mozilla 為什麼會發生這種情況後,才知道該錯誤:https ://bugzilla.mozilla.org/show_bug.cgi?id=1662232
pgrep
與程序名稱匹配,由ps
without報告,-f
而與由或您的 non-standardpgrep -f
報告的參數列表匹配。ps -f``ps aux
firefox
更改其執行緒的名稱以辨識每個執行緒的功能。嘗試(假設預設值
$IFS
):ps -L -o comm= -p $(pgrep -wf firefox)
其中列出了程序中所有執行緒的名稱,其參數列表包含
firefox
,您會看到很多類似的內容:MainThread gmain gdbus Gecko_IOThread Timer Netlink Monitor Socket Thread Permission JS Watchdog JS Helper [...]
因此,對於
firefox
,您可能希望在參數列表(他們或他們的父母執行的最後一個命令中的參數列表,如果有的話)上匹配(如果要列出所有執行緒,則pgrep -f firefox
添加)而不是程序/執行緒名稱。-w
或者pgrep -f '^[^ ]*firefox'
僅匹配該 arg 列表的第一個單詞(pgrep
在匹配之前將參數與空格連接,如 inps -f
)。在任何情況下,任何程序都可以將其程序名稱或參數列表設置或更改為他們想要的任何內容¹,因此以這種方式查找程序絕不是萬無一失的。
如果您想匹配目前正在執行
/usr/lib/firefox/firefox
執行檔的程序,請在 Linux 上使用zsh
:print -rC1 /proc/<1->/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)
或者對於執行緒:
print -rC1 /proc/<1->/task/*/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)
(請注意,如果您沒有超級使用者權限,您可能無法獲取未以您身份執行的程序的資訊)。
或者可能稍微更便攜
lsof
:lsof -Fd /usr/lib/firefox/firefox | sed '/^p/h;/^ftxt/!d;g;s/^p//'
或者對於執行緒:
lsof -K -FKd /usr/lib/firefox/firefox | sed '/^K/h;/^ftxt/!d;g;s/^K//'
¹ 儘管請注意,程序名稱長度通常是有限的(Linux 上為 15 個字節),並且取決於作業系統和作業系統版本,並非所有 arg 列表都可以輕鬆地被系統提供以供檢查。