reveal

A Mac OS X shell script
to reveal files and folders in the Finder
from the Terminal application

This shell script example code constructs an ad hoc AppleScript program then executes it with the osascript command.

Did you know that you can run an AppleScript from a shell script? I learned about it in the AppleScript in a Nutshell book, which is very good. I hope you find the shell script below useful as sample code.

Example use of my reveal script:

Z% reveal -v ~/Documents
[osascript -e '
    tell application "Finder"
        reveal { ¬
            item ":Users:yost:Documents" of startup disk ¬
        }
        activate
    end tell
']
Z%

The Finder activates; my home folder is open, and the Documents folder in my Home folder is selected.

To use the shell script

Download the reveal shell script file (don't copy and paste from this web page), then make it executable and put the file into a folder in your $PATH.


#!/bin/zsh

commandName=${0##*/}

usage() {
  if [[ $1 != '' ]] ; then echo 1>&2 "\n$1" ; fi
  echo 1>&2 "
Usage: $commandName
       $commandName [ -l ] [ -v ] item ...
     
Tells the Finder to reveal the current directory or a list of the given items.
The -l argument tells the Finder to set the last window it opens to list view.
The -v argument causes the AppleScript to be echoed to stderr.

In the multiple-arguments case, the Finder will open one window that cantains
all of the items and select them all.  Maybe someday it will do that even if
the items are not all in the same folder (using list view and expanded subfolders).

Author: Dave@Yost.com  2002-12-09, 2004-06-05, 2006-07-07, 2011-11-24
Version 1.3
"
  exit 2
}

zparseopts -D -K - -help=argHelp l=argList v=argVerbose

if [[ $#argHelp != 0 ]] ; then
  usage
fi

case $1 in
-*) usage "Unknown option: $1"
  ;;
esac

#-----------------------------------------

# unix path -> old-style Mac path for AppleScript
colonize() {
  sed 's,.*,"&",
       s,/,\&,g
       s,:,/,g
       s,^"&Volumes&,",
       s,^"&.*,& of startup disk,' \
  | sed 's,&,:,g' \
  | tr -d '\012'
}

# Reveal unix paths in the Finder
doReveal() {
  if [ $# = 0 ] ; then
    args=( . )
  else
    args=( $* )
  fi

  itemList=
  for x in $args
  do
    case "$x" in
    /*) item="$x" ;;
    .)  item="`/bin/pwd`" ;;
    *)  item="`/bin/pwd`/$x" ;;
    esac
    
    # All /x/../ -> /
    previtem=
    while [ "$previtem" != "$item" ]
    do
      previtem="$item"
      item=`echo "$item" | sed 's,[^/]*/\.\./,,'`
    done
    
    if [ $item = / ] ; then
      itemColonized="startup disk"
    else
      itemColonized="item $(echo -n $item | colonize)"
    fi
    
    # Add it to the list
    if [ "$itemList" = "" ] ; then
      itemList="¬
      $itemColonized"
    else
      itemList="$itemList, ¬
      $itemColonized"
    fi
  done
  
  script='
  tell application "Finder"
    reveal { '$itemList' ¬
    }'
  if [ "$#argList" != 0 ] ; then
    script="$script
    get every Finder window whose index is 1
    set the current view of item 1 of the result to list view"
  fi
  script="$script"'
    activate
  end tell'
  if [[ $#argVerbose != 0 ]] ; then
    echo 1>&2 "[osascript -e '$script
']"
  fi
  osascript -e "$script"
}

test() {
  # If there are any mounted volumes, try the first one.
  mountedVolume=`mount | grep Volumes | sed -n '1s,^[^ ]* on \(.*\) (*[^(]*,\1,p'`
  if [ "$mountedVolume" != "" ] ; then
    $commandName "$mountedVolume"
  fi
  cd /Library
  $commandName
  $commandName "/"
  $commandName Preferences
  $commandName "/Applications/QuickTime Player.app" \
       "/Applications/Utilities/Java/../../System Preferences.app"
}

case $# in
0) doReveal "`/bin/pwd`"
   ;;
*) case "$1" in
   --test)
      test
      ;;
   *) doReveal $*
      ;;
   esac
   ;;
esac

http://Yost.com/computers/macstuff/reveal/ - this page
2002-12-06 1.0 Created
2005-04-10 1.1 Modified to add -v which is no longer the default
2006-07-07 1.2 Modified the script. Something changed in the OS that broke it.
2011-11-24 1.3 fixed to work correctly if name is not 'reveal'