Default browser script
April 10, 2012 at 12:16 AM by Dr. Drang
Here’s a quick little Python script for getting the default browser on a Mac. It’s the sort of thing that can be useful in an AppleScript,
set home to POSIX path of (path to home folder)
set defaultBrowser to (do shell script home & "bin/default-browser")
tell application id defaultBrowser
[blah blah blah]
end tell
or in an open
command when you want to force a non-HTML file to open in your browser,
db=`~/bin/default-browser`; open -b $db file.txt
John Gruber has used Perl and its Mac::InternetConfig
library to do this sort of thing, but I don’t want to use Perl and I especially don’t want to use a library named after a utility I used back in the System 7 and 8 days.1
Your default browser is one of the many pieces of information kept in the Launch Services property list file, which is at
~/Library/Preferences/com.apple.LaunchServices.plist
You need to open that file, search through it to find the http
entry, and get its bundle identifier. Here’s the script that does it, which I call default-browser
and keep in my ~/bin
directory.
python:
1: #!/usr/bin/python
2:
3: from plistlib import readPlist
4: from os import environ, remove
5: from shutil import copy
6: from tempfile import mkstemp
7: from subprocess import call
8:
9: # Copy the original Launch Services preferences to a temporary file.
10: f = environ['HOME'] + "/Library/Preferences/com.apple.LaunchServices.plist"
11: (handle, tf) = mkstemp(suffix='.plist', dir=environ['HOME'])
12: copy(f, tf)
13:
14: # Convert the binary plist to an XML plist.
15: call(['plutil', '-convert', 'xml1', tf])
16:
17: # Read through the plist and pluck out the default browser.
18: pl = readPlist(tf)
19: for i in pl['LSHandlers']:
20: if ('LSHandlerURLScheme' in i) and i['LSHandlerURLScheme'] == 'http':
21: print i['LSHandlerRoleAll']
22: break
23:
24: # Delete the temporary file.
25: remove(tf)
Python has a nice plistlib
library that knows how to read a property list file and turn it into a Python dictionary. Unfortunately, the library seems to work only on property lists that are stored as XML files, and the Launch Services plist is stored in binary format.
To get around this problem, we create a temporary file (Line 11), copy the binary plist to it (Line 12), and then convert the copy from binary to XML through the built-in plutil
command (Line 15). Then we can search through the dictionary entry to find the handler associated with the http
protocol (Lines 18-22).2
The Python tempfile
library has some methods that create self-destroying file objects, but since we need a real file to run plutil
on, we had to use the mkstemp
method, which doesn’t clean up after itself. Thus, the file deletion on Line 25.
The output of default-browser
is a bundle identifier, one of those things that looks like a backward domain name. For the three most popular browsers, the identifiers are
Browser | Bundle ID |
---|---|
Safari | com.apple.safari |
Chrome | com.google.chrome |
Firefox | org.mozilla.firefox |
If you want to write scripts that work under different browsers, a utility like default-browser
can be handy.
-
There’s a Python library with essentially the same name, and I don’t want to use it, either. ↩
-
How did I know the names of the dictionary keys? I opened the plist file in XCode and looked through it for the names. ↩