Using duti to script default applications for Macs

Back story

It was surprisingly difficult for me to find a straightforward tutorial on how to script changing the default applications for Macs. There are great screenshot-laden tutorials on how to change default applications the point-and-click way for one user (right-click the file, Get Info, Open With, select application, Change All, Continue). And then there are vague mentions of how complicated lsregister is. Eventually I found a semi-consensus in the Mac Admin communities about using duti to change default applications for users, but I still couldn't find a simple tutorial on how to get it up and running.

I thought the logical thing to do would be to go to the downloads page for duti and then follow the instructions (which involve compiling it from source). For some reason, I couldn't get the ./configure to work.

In case anyone else is frustrated in a similar way, the tutorial below goes out to you.

Get duti

Make sure you have Homebrew set up:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
and then use Homebrew to install duti:
brew install duti
This will install a binary of duti to /usr/local/Cellar/duti/#.#.#/bin/duti (#.#.# as of this writing is actually 1.5.3). Once you have this binary, you can copy it to somewhere else, and it'll run just fine there—it's a self-contained executable.

For the sake of simplicity, I would recommend moving it to /usr/local/bin instead, so the path to it would be /usr/local/bin/duti instead of that long Cellar path.

Creating a duti configuration file

Apparently, there are three forms duti configuration can take (including a specially-formatted XML file), but for starters I found the straight tab-delimited text file to be the easiest.

Here's an example of a text file (which I called AudioVideo.duti) to make VLC the default media player for a bunch of audio and video types:

# bundle id UTI role
org.videolan.vlc avi viewer
org.videolan.vlc flac viewer
org.videolan.vlc flv viewer
org.videolan.vlc m4a viewer
org.videolan.vlc mkv viewer
org.videolan.vlc mov viewer
org.videolan.vlc mp3 viewer
org.videolan.vlc mp4 viewer
org.videolan.vlc mpg viewer
org.videolan.vlc wav viewer
org.videolan.vlc wmv viewer
Please remember to include a carriage return at the end of the last line of the file; otherwise, duti will complain that the last line is too long.

You can find the bundle identifier by right-clicking the .app, selecting Show Package Contents and then going to Contents/Info.plist. Look for CFBundleIdentifier.

Here's an example, too, of how to use duti to Set Outlook 2016 as default without having to open Mail.app.

Create a script that scans the configuration file(s)

As far as I can tell, duti changes defaults on a per-user basis and not system-wide. So the best thing I've found is to use a login script (which, for this example, is called RescanDuti.sh) to scan the settings to be applied:

#!/bin/bash

# Delay start for a few seconds. If it runs too early, the change won't register.
sleep 5

# Run the command to register the changes
/usr/local/bin/duti /Library/Application\ Support/duti
The first command (to pause for 5 seconds) is optional. The change actually does register... if the user already exists. But we run a lot of our computers bound to the domain, so if a user logs into a random computer, she may not already have an existing user profile on that Mac. Based on a few tests I've done with user profiles being created, it seems about 5 seconds is a good delay to make sure the user is logged in before scanning for duti configuration files.

The next command just runs duti and tells it to scan a certain directory for any configuration files. I put the AudioVideo.duti file in the /Library/Application Support/duti folder. If I had .duti files for text files and web browser files, I'd also put those in the same /Library/Application Support/duti folder to be scanned.

Create a Launch Agent to invoke the script at login

Don't bother making your own Launch Agent. Just make the duti rescan a login-every script for outset.

Distribute the executable, Launch Agent, and script

I'm assuming if you want to script this that you have ways you're already familiar with to distribute these things (Munki, Casper, Puppet, ARD). My preferred method in a case like this is to use Packages to distribute the payloads to their respective places (dockutil to /usr/local/bin, AudioVideo.duti to /Library/Application Support/duti). Then I use Munki to distribute it to client machines.

Further reading

Read duti's official documentation for more details about different commands you can use and the XML format if you prefer that to a plain old text file.

One thought on “Using duti to script default applications for Macs”

Leave a Reply

Your email address will not be published. Required fields are marked *