Controlling the Mac user interface from the shell

[2012-10-11] jsshell, dev, shell, mac
(Ad, please don’t block)
The Mac OS X shell has several Mac-only commands for communicating with the graphical user interface (GUI). They are useful in three cases: First, when switching back and forth between shell and GUI. Second, when interacting with the system from a language that is not Objective C or AppleScript: Bash, Node.js [1], Python etc.

open

The open command performs multiple tasks. The following subsections give an overview, consult the man page for complete documentation:
    man open
If you use open programmatically (instead of interactively via a shell) then it helps to know the long forms of the options. You can list those by calling open without any arguments.
    open

open and files

You can use open to work with files:
  • Open a folder in the Finder:
        open .
    
  • Open a file in the application that has been associated with it (which can be overridden per file):
        open index.html
    
  • Reveal a file in the Finder (instead of opening it):
        open -R index.html
    
  • Open a file with a given application:
        open -a firefox index.html
    
There are two ways to go in the opposite direction, to get a path from the Finder to the Terminal: First, drag and drop a file or folder on a Terminal window and its path will be pasted into it. Second, copy a file or folder in the Finder and paste in a Terminal window.

open and URLs

open also works with URLs:
  • Open a URL:
        open http://example.com
    
  • Open a mailto: URL to generate an email:
        open 'mailto:joe@example.com?subject=Hi&body=Hi%20Joe!'
    
    Check [2] for details.

open and text editors

open sometimes uses the default text editor. That editor can be configured via the “Get Info” window: Open it for a .txt file, change the ”Open with” app to your liking, click “Change all...”. The current mappings can be looked up in the file
    ~/Library/Preferences/com.apple.LaunchServices.plist
An answer on Super User provides more information on what is going on here.

open has the following options for working with text editors:

  • Open a file in TextEdit:
        open -e README.md
    
  • Open a file with the default text editor:
        open -t README.md
    
  • Read stdin, open the result in the default text editor. For example, the following command reads input from the keyboard and puts what you have typed in new window.
        open -f
    
    Another example: open the text “Hello World!” in a new window.
        echo 'Hello World!' | open -f
    
    On my system, -f always used TextEdit, so your mileage may vary.
Openurl [3] is a library for opening URLs on Node.js. It uses open on the Mac.

osascript

osascript is a command that allows you to execute AppleScript code via the shell. Many things under Mac OS X can only be automated via AppleScript (Finder, iTunes, ...). For example, jsreload [4] uses the following code to reload the first tab of Chrome:
	tell application "Google Chrome"
	    tell tab 1 of window 1 to reload
	end tell
To execute that code on a Bash command line, type:
    osascript <<-END
    tell application "Google Chrome"
    tell tab 1 of window 1 to reload
    end tell
    END

pbpaste and pbcopy

pbpaste and pbcopy interact with the clipboard (pb is short for “pasteboard”). pbpaste writes the clipboard to stdout, pbcopy replaces the clipboard with what it receives via stdin.

Example – changing the clipboard (e.g. if the current content of the clipboard is the plain text "Hello World", then it becomes "Hell- W-rld").

    pbpaste | sed -e s/o/-/g | pbcopy
Example – writing the clipboard to a text file:
    pbpaste > file.txt
Example – creating a bookmarklet: Take a JavaScript file, convert it to a single compact line via uglify.js, prepend the protocol "javascript:" and copy the resulting bookmarklet URL to the clipboard.
    (echo -n "javascript:"; uglifyjs --no-copyright foo.js ; echo) | pbcopy
The option --no-copyright means that uglify.js will remove leading comments. One such comment might mention the above command, as a quick reference.

References

  1. Write your shell scripts in JavaScript, via Node.js
  2. Generate emails via mailto URLs on Node.js
  3. openurl – a Node.js module for opening URLs
  4. Reload a web browser when a file changes (Node.js, Grunt, Mac)