How create an OS X service that passes a file's path to a shell script?

Solution 1:

Select to create a Service in Automator that receives selected files and folders as input in Finder only. Add the Run Shell Script action and pass input as arguments.

The arguments you receive are the full Unix paths of the selected files and folders. Using growlnotify, part of Growl for demonstration purposes:

enter image description here

Growl message as a result of running it on a file:

enter image description here

The command appears in the context menu of a file or folder in Finder. If there are too many applicable Services, they are grouped into a submenu Services.

enter image description here


If your script requires both the full file path, and the file name, you can do something like the following, first extracting the file name from the full path:

for f in "$@"
do
    name="$( basename $f )"
    /usr/local/bin/growlnotify "$name" -m "$f"
done

You can see that the file name is used as title, while the path is used as message in Growl:

enter image description here


If you need to query for additional input, you can execute a short AppleScript to do that. The following is a complete shell script (like the growlnotify above) that queries for input, and renames the selected file to that new name. I did not include error handling and such, e.g. adding colons and slashes to the new file name will likely break the script.

    # repeat for every file in selection
for f in "$@"
do
    # capture input of a simple dialog in AppleScript
    OUT=$( osascript -e "tell application \"System Events\" to text returned of (display dialog \"New Name of $f:\" default answer \"\")" )
    # if the user canceled, skip to the next file
    [[ $? -eq 0 ]] || continue
    # old file name is the loop variable
    OLD="$f"
    # new file name is the same directory, plus the user's input
    NEW="$( dirname "$OLD" )/$OUT"
    # print a message announcing the rename
    /usr/local/bin/growlnotify "Renaming…" -m "$OLD to $NEW"
    # perform the actual rename
    mv "$OLD" "$NEW"
done

Screenshot of a sample rename action announced via growlnotify:

enter image description here