Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

How can I change the default app for all files of a particular file type through the Terminal in OS X?

share|improve this question
    
Not a dupe, even though I kind of answered it there. Sorry about that. –  Daniel Beck Apr 21 '11 at 17:25
    
For power use, I like the accepted answer under a more recent Super User question, Is there a faster way to change default apps associated with file types on OS X?. For simplicity, I like Daniel's answer below. –  Graham Perrin Apr 29 '12 at 13:08

1 Answer 1

Edit ~/Library/Preferences/com.apple.LaunchServices.plist.

Add an entry under LSHandlers, containing the UTI (key LSHandlerContentType, e.g. public.plain-text) and application bundle identifier (LSHandlerRoleAll, e.g. com.macromates.textmate).

It looks like this in Property List Editor:

alt text alt text

To do this from the command line, use defaults or /usr/libexec/PlistBuddy. Both have extensive manpages.

For example to open all .plist files using Xcode:

defaults write com.apple.LaunchServices LSHandlers -array-add '{ LSHandlerContentType = "com.apple.property-list"; LSHandlerRoleAll = "com.apple.dt.xcode"; }'

Of course, you'd need to make sure there's not already another entry for the UTI com.apple.property-list already in there.

Here's a more complete script that'll remove existing entries for a UTI and add a new one. It can only handle LSHandlerContentType, and will always set LSHandlerRoleAll, and has hard-coded bundle IDs instead of parameters. Other than that, it should work quite well.

#!/usr/bin/env bash

PLIST="$HOME/Library/Preferences/com.apple.LaunchServices.plist"
BUDDY=/usr/libexec/PlistBuddy

# the key to match with the desired value
KEY=LSHandlerContentType

# the value for which we'll replace the handler
VALUE=public.plain-text

# the new handler for all roles
HANDLER=com.macromates.TextMate

$BUDDY -c 'Print "LSHandlers"' $PLIST >/dev/null 2>&1
ret=$?
if [[ $ret -ne 0 ]] ; then
        echo "There is no LSHandlers entry in $PLIST" >&2
        exit 1
fi

function create_entry {
        $BUDDY -c "Add LSHandlers:$I dict" $PLIST
        $BUDDY -c "Add LSHandlers:$I:$KEY string $VALUE" $PLIST
        $BUDDY -c "Add LSHandlers:$I:LSHandlerRoleAll string $HANDLER" $PLIST
}

declare -i I=0
while [ true ] ; do
        $BUDDY -c "Print LSHandlers:$I" $PLIST >/dev/null 2>&1
        [[ $? -eq 0 ]] || { echo "Finished, no $VALUE found, setting it to $HANDLER" ; create_entry ; exit ; }

        OUT="$( $BUDDY -c "Print 'LSHandlers:$I:$KEY'" $PLIST 2>/dev/null )"
        if [[ $? -ne 0 ]] ; then 
                I=$I+1
                continue
        fi

        CONTENT=$( echo "$OUT" )
        if [[ $CONTENT = $VALUE ]] ; then
                echo "Replacing $CONTENT handler with $HANDLER"
                $BUDDY -c "Delete 'LSHandlers:$I'" $PLIST
                create_entry
                exit
        else
                I=$I+1 
        fi
done
share|improve this answer
1  
The easiest way is probably to x=~/Library/Preferences/com.apple.LaunchServices.plist; plutil -convert xml1 $x; open -a TextEdit $x and copy and paste those LSHandlers entries. To get the bundle identifier you can do osascript -e 'bundle identifier of (info for (path to app "TextEdit"))'. –  Lri Apr 22 '11 at 6:24
    
@Lri In a way, yes, but this question is specifically about the command line. I figured that TextEdit (or Property List Editor / Xcode) doesn't qualify; I just copied over that part with Property List Editor from my other answer for illustration purposes. Useful remark on the bundle identifier. –  Daniel Beck Apr 22 '11 at 8:40
    
Credit to Daniel, I borrowed from this for an answer to a question in Ask Different, Can Finder and the “open” command treat files with .sh or other typical extensions just like .command files?. –  Graham Perrin Apr 29 '12 at 13:11
    
If there does exist an alternative entry for the UTI, would you agree that "command line removal of a single dictionary from an array may be unnecessarily difficult"? –  Graham Perrin Apr 29 '12 at 13:14
1  
@GrahamPerrin It is unnecessarily difficult because defaults doesn't seem to be capable to do it, and it requires a few PlistBuddy calls. But it's possible to do it in a reusable shell script. –  Daniel Beck Apr 29 '12 at 18:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.