(If you just want to know my solution, skip to Reading .desktop
Files.)
Update: xdg-settings get default-web-browser
should work instead of my solution5. Why was this nowhere in search results for this problem? I have no clue. It should be a very obvious answer.
Linux is a very powerful operating system that gets more user-friendly by the year, but it still has glaring holes. Today, I discovered there is no reliable method to finding out if a browser is installed.
Searching online reveals that most people only care about knowing if specific browsers are installed, or are content with the incomplete option of only checking for the most popular browsers (currently Chrome, Firefox, and Opera). The which
command works fine combined with a resource like LinuxConfig.org’s List of Browsers available on Linux, but now your script requires periodic maintenance to add more browsers to the list1.
The next most common answer online is to see if xdg-open
exists, based on the assumption that a browser must be installed if xdg-open is installed – this is simply false. You also can’t query xdg-open to see if it can handle URLs without opening a URL. If you use this method, you are effectively attacking the user with a pop-up2.
I’ve also found documentation for update-alternatives
, but it requires knowing exactly what name it uses for browser entries. I was told to use x-www-browser
, gnome-www-browser
, and just www-browser
. None of these work, and the command doesn’t allow you to list all of its entries because the --all
option forces you into an interactive session to configure every single option it has. I refuse to go through that mess just to find how browsers are defined.
This should be simple, shouldn’t it?
Worse, I’ve also found multiple users stating that this fails to adhere to system defaults on Ubuntu, despite it being Ubuntu’s official default method.. and it doesn’t even WORK.
There’s also Debian Wiki’s DefaultWebBrowser which is somehow too dense and too sparse, and in light of what I’ve already tried – nonsensical. Suggesting the use of a $BROWSER
environment variable strikes me as particularly insane6.
The best option I can find right now is to manually scan every menu entry for programs categorized with WebBrowser
3. This still excludes some options, is convoluted, and has the possibility of failing due to mistakes in menu entries. But it’s the closest to a future-facing solution I could find.
Reading .desktop
Files
Update: xdg-settings get default-web-browser
basically has already done what I was doing here5. If anything has a .desktop
file for a browser, that should return whatever default has been selected, thus telling you a browser is installed.4
Menus in Linux use a standard format to describe programs/actions so they can be automatically organized. Even some CLI apps create these entries as well. These are organized by predefined Categories, including WebBrowser
. While this may still exclude some niche browsers, the users of such browsers likely will know how to handle this incompatibility, and are very very rare.
The only issue with this solution is finding the files and having to parse them yourself. This is still a little tedious, but will last longer and detect new browsers automatically. Unfortunately, the only information I found on where these files should be is conflicting slightly. The Arch wiki says they are in 3 specific locations, but the actual spec excludes one of those and specifies an environment variable where the rest are located. So I check all of these locations, scan every file, and look for two things: 1) A Categories key with “WebBrowser” in it. 2) No Hidden key.
For my specific use case, since I only need to know a browser is installed, I can exit this search on the first hit, but obviously you can use the spec to actually find which browsers are installed, and even launch them or show their icons!
For reference’ sake, here’s what a .desktop
file for LibreWolf could look like:
[Desktop Entry]
Type=Application
Name=LibreWolf
Comment=Privacy-focused web browser
Exec=/path/to/librewolf
Icon=/path/to/icon.png
Categories=Network;WebBrowser;
Footnotes
- Any decision that adds future maintenance costs should be made very carefully and avoided if possible. Do you really want to devote a portion of the rest of your life to making sure this keeps functioning? Do you really want to limit your list of acceptable browsers to only what’s popular now?
- How long has it been and we still don’t force applications to open without stealing window focus at an OS level? There are always heavyweight applications, no matter how fast computers get, and computers are fundamentally designed for multitasking. We should be able to start a program and do something else while waiting for it to open, without the risk of random inputs being sent to the program when it is finally ready. Combine this with the fact that many programs steal focus before they’re even ready to accept input and it’s a garbage user experience.
- Thanks to Arran Ubels on StackOverflow for helping me find this answer.
- In theory, a browser could still be installed that has its desktop file in the wrong place, but then it is likely the system won’t recognize it for using
open
or similar commands anyhow. For my use case, that means it is not worth continuing to look for a browser being installed, but depending on what you’re doing, you may want to search further. Heck, if it’s really important, you might want to find every desktop file on the computer to check for a browser – though at that point you should probably just be doing something to ensure a browser is ready yourself instead of trying so hard to find an extant badly configured browser.. - Thanks to @CcxCZ on Telegram for telling me about this command!
- It was pointed out to me that I should elaborate on this: Environment variables are easily manipulated and overwritten accidentally when they have simple names. (For a counter-example, I don’t worry about referencing
$XDG_DATA_DIRS
because it is unlikely to be screwed up.)