Ubuntu

為什麼“pgrep firefox”不能在 Ubuntu 20.04 上執行

  • September 3, 2020

正如標題所示,Ubuntu 20.04 上的以下命令:

pgrep firefox

… 不返回任何結果。

同時,以下命令:

ps aux |grep firefox

… 返回 6 個結果,其中 5 個應該匹配pgrep firefoxpgrepUbuntu 上的原始命令有什麼問題?

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 執行時,它會寫入值MainThreadto /proc/<pid>/comm(感謝 @steeldriver 在上面的評論/問題部分指出這一點)
  • pgrep然後使用來自/proc/<pid>/comm, 的值來查找匹配命令
  • |管道分隔符允許pgrep匹配多個值。建議保留firefoxANDMainThread以便此命令在舊版本(例如 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與程序名稱匹配,由pswithout報告,-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在匹配之前將參數與空格連接,如 in ps -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 列表都可以輕鬆地被系統提供以供檢查。

引用自:https://unix.stackexchange.com/questions/607226