# To associate Terminal with .sh files, 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: 

- command line removal of a single dictionary from an array may be unnecessarily difficult
- 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.

## 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][1] to Super User question [Is there a faster way to change default apps associated with file types on OS X?][2] suggests: 

> - Requires 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?][3]

----

# 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][4]) we see that Terminal is designed to support `com.apple.terminal.shell-script` 

- `public.shell-script ` (the [system-declared UTI][5] associated with `.sh`) is not supported at that level, it appears elsewhere in the property list — under `UTExportedTypeDeclarations`

### Credit ###

To [Daniel Beck][6] for his Super User answer under [How to change default app for all files of particular file type through terminal in OS X?][7]. 


  [1]: http://superuser.com/a/341429/84988
  [2]: http://superuser.com/q/305498/84988
  [3]: http://apple.stackexchange.com/q/50004/8546
  [4]: https://developer.apple.com/library/mac/#documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
  [5]: http://developer.apple.com/library/ios/#documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
  [6]: http://stackexchange.com/users/11921/daniel-beck
  [7]: http://superuser.com/q/273756/84988