# To associate Terminal with .sh files, with the defaults command, without using Finder to change a preference # In most cases, all that's required should be possible from the command line … ## Preparation ## Two commands: `defaults read com.apple.LaunchServices | grep -B 1 -A 3 public.shell-script` `defaults read com.apple.LaunchServices | grep -B 1 -A 4 "LSHandlerContentTag = sh;"` ### If either command reveals an existing preference ### Use Xcode or any other suitable property list editor to remove the relevant dictionary from the `LSHandlers` key within the following file: `~/Library/Preferences/com.apple.LaunchServices.plist` Hints: - `defaults`, with which I'm more familiar, seems unsuitable for removal of a single dictionary from an array - removal should be necessary only if (say) the user has previously used Finder to associate `.sh` files with an application other than the system default - [a Super User answer][1] under [How to change default app for all files of particular file type through terminal in OS X?][2] is recently edited to include a script that uses `PlistBuddy` — credit to [Daniel Beck][3]. ## Adding to LaunchServices preferences, for Terminal to view and edit .sh files ## Two one-line commands. Depending on your requirements, the first command alone may suffice: `defaults write com.apple.LaunchServices LSHandlers -array-add '{ LSHandlerContentType = "public.shell-script"; LSHandlerRoleViewer = "com.apple.Terminal"; LSHandlerRoleEditor = "com.apple.Terminal"; }'` `defaults write com.apple.LaunchServices LSHandlers -array-add '{ LSHandlerContentTag = "sh"; LSHandlerContentTagClass = "public.filename-extension"; LSHandlerRoleViewer = "com.apple.Terminal"; LSHandlerRoleEditor = "com.apple.Terminal"; }'` ## For the new preferences to be respected ## ### First attempt, an experiment ### After editing the .plist I tried logging out of the system, then logging in. This did not have the desired effect. ### Second attempt ## Maybe not the best approach for modern releases of the system, these two commands seem effective: `/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill` `/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -seed -v` - option `-v` only if you want a verbose view of progress. After the scan completes — after the Launch Services database has been seeded — you should find that `.sh` files open in Terminal in response to an `open` command. ### Probably best ### The [accepted answer][4] to Super User question [Is there a faster way to change default apps associated with file types on OS X?][5] suggests: > … restarting the OS to apply changes (logging out and back in isn't enough) … A question arises: [Why is a command line change to ~/Library/Preferences/com.apple.LaunchServices.plist not effective immediately?][6] ---- # Background # ## Understanding Terminal.app support for .sh (public.shell-script) ## Consider the result of the following command: `defaults read /Applications/Utilities/Terminal.app/Contents/Info` - under `CFBundleDocumentTypes` ([an array of dictionaries describing the document types supported by the bundle][7]) we see that Terminal is designed to support `com.apple.terminal.shell-script` - `public.shell-script ` (the [system-declared UTI][8] associated with `.sh`) is not supported at that level, it appears elsewhere in the property list — under `UTExportedTypeDeclarations` [1]: http://superuser.com/a/273770/84988 [2]: http://superuser.com/q/273756/84988 [3]: http://stackexchange.com/users/11921/daniel-beck [4]: http://superuser.com/a/341429/84988 [5]: http://superuser.com/q/305498/84988 [6]: http://apple.stackexchange.com/q/50004/8546 [7]: https://developer.apple.com/library/mac/#documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html [8]: http://developer.apple.com/library/ios/#documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html