6

As the title suggests, the following command on Ubuntu 20.04:

pgrep firefox

... returns no results.

Meanwhile, the following command:

ps aux |grep firefox

... returns 6 results, 5 of which should match pgrep firefox. What's wrong with the original pgrep command on 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

Running the same command on Ubuntu 18.04 and macOS works just fine.

7
  • 1
    Can you confirm whether pgrep -f firefox works? Are the versions of firefox the same in both Ubuntus? I suspect you'll find that it's not "pgrep on Ubuntu" that's responsible - it's Firefox, for apparently writing MainThread or Web Content or somesuch instead of firefox to /proc/<pid>/comm... Commented Aug 31, 2020 at 17:59
  • pgrep -f firefox works but it also returns false-positives for e.g. a process started as gedit ~/Desktop/firefox.txt. What's a good way to see exactly what's writing in /proc/<pid> so that I can search for that as an interim?
    – tresf
    Commented Aug 31, 2020 at 18:27
  • Ubuntu 18.04 (working) has Firefox 78. Ubuntu 20.04 (not working) has Firefox 79.
    – tresf
    Commented Aug 31, 2020 at 18:30
  • cat /proc/81646/comm returns MainThread as suspected. Checking 18.04.
    – tresf
    Commented Aug 31, 2020 at 18:33
  • The same command on 18.04 returns firefox, not MainThread as predicted.
    – tresf
    Commented Aug 31, 2020 at 18:36

2 Answers 2

5

pgrep matches against the process name, as reported by ps without -f while pgrep -f matches against the argument list as reported by ps -f or your non-standard ps aux.

firefox changes the names of its threads to identify what each does.

Try (assuming the default value of $IFS):

ps -L -o comm= -p $(pgrep -wf firefox)

Which lists the names of all of the threads from processes with an argument list that contains firefox, and you'll see a lot of things like:

MainThread
gmain
gdbus
Gecko_IOThread
Timer
Netlink Monitor
Socket Thread
Permission
JS Watchdog
JS Helper
[...]

So for firefox, you may want to match on argument list (argument list from the last command they or their parents executed if any) with pgrep -f firefox (add -w if you want to list all threads) rather than process/thread name. Or pgrep -f '^[^ ]*firefox' to match only on the first word of that arg list (pgrep joins the arguments with spaces before matching, like in ps -f).

In any case, any process can set or change their process name or argument list to anything they want¹, so finding processes that way is never foolproof.

If you wanted to match on process that are currently running the /usr/lib/firefox/firefox executable, on Linux and with zsh:

print -rC1 /proc/<1->/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)

Or for the threads:

print -rC1 /proc/<1->/task/*/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)

(note that if you don't have superuser privileges, you may not be able to get that information for processes not running as you).

Or possibly slightly more portably with lsof:

lsof -Fd /usr/lib/firefox/firefox | sed '/^p/h;/^ftxt/!d;g;s/^p//'

Or for threads:

lsof -K -FKd /usr/lib/firefox/firefox | sed '/^K/h;/^ftxt/!d;g;s/^K//'

¹ though note that process name length is often limited (15 bytes on Linux), and depending on OS and OS version, not all of the arg list is easily made available by the system for inspection.

6
  • Thanks for the list of process/thread names. The -f is still volatile. For example, if you write a program called /helper_firefox it would require more filtering. Furthemore, this behavior is not present on the latest Firefox on macOS meaning that this special thread labeling is and will continue to break long-running assumptions by power users and system administrators. I've filed a bug report to Mozilla as a result. Hopefully they have a good justification for breaking such a common command.
    – tresf
    Commented Aug 31, 2020 at 19:43
  • @tresf, see edit. Searching processes by name gives no guarantee. Commented Aug 31, 2020 at 19:46
  • The /proc/ technique is nice, but in my experience when deploying to macOS and Solaris, this doesn't scale well.
    – tresf
    Commented Aug 31, 2020 at 19:46
  • Searching processes by name gives no guarantee. Agreed, but it seems much more likely that searching for a process by exact name firefox is more reliable and thus more likely to be reliable than a wildcard thereof. e.g. "Don't call your script|project|process firefox" is (in my opinion) a much more sane of a downstream bug report title than "Don't put firefox anywhere in the name".
    – tresf
    Commented Aug 31, 2020 at 19:48
  • @trestf, pgrep firefox is wildcard, pgrep takes a regexp as argument like grep, it's the re in pgrep. pgrep -x firefox same as pgrep '^firefox$' if you want to match on process names that are firefox. Commented Aug 31, 2020 at 19:50
2

Why doesn't pgrep firefox work on Ubuntu 20.04

Because it's a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1649010.

A workaround is:

pgrep "firefox|MainThread"

Why this works?

  • When Firefox 79 on Ubuntu is running, it writes a value of MainThread to /proc/<pid>/comm (thanks to @steeldriver for pointing this out in the comments/questions section above)
  • pgrep then uses uses the value from /proc/<pid>/comm, to find match the command
  • The | pipe delimiter allows pgrep to match multiple values. Keeping firefox AND MainThread is recommended so that this command still succeeds on older versions -- such as Ubuntu 18.04 + Firefox 78 -- where pgrep firefox is still working fine.

Why might this be inaccurate?

  • WARNING: Any process with a process name of MainThread that is NOT firefox will also report as running using this technique. Use with caution.
  • WARNING: Multiple processes may be active. See this answer to find out why: https://unix.stackexchange.com/a/607242/190347
  • NOTE: For an exact match pgrep -x "firefox|MainThread" is recommended

What other options do we have?

  • As @steeldriver points out, one can infer that pgrep -f firefox is a suitable replacement. It suffers a similar fate as MainThread where it may match commands which contain firefox in them (such as a directory name, file name, etc). For this reason, I find it more likely to match rogue processes -- and thus more likely to throw a false-positive -- than the MainThread string. This is a hunch based on experience, not documented evidence however a quick search on GitHub shows that MainThread is not a common project name (58 results, as opposed to firefox matching 21,000 repositories)
  • Alternately, using a combination of commands/techniques to filter out false-positives may be preferred over all others (such as finding a union of results from both commands)
  • Ask. Knowledge of the bug came after asking Mozilla directly why this is happening: https://bugzilla.mozilla.org/show_bug.cgi?id=1662232

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .