16

I'm coming from Linux where it's easy to run a script against a set of files in nautilus or dolphin, but I was kind of surprised to see that this isn't easy in OSX.

Preferably, I would love to be able to ctrl-click on some selection in finder, choose my script, and have a terminal window pop up to show progress or any user interaction.

8 Answers 8

9

The easiest, built-in way to do this is to just drag the items from Finder to a Terminal window. When you drop them, Terminal will “type” their (escaped) pathnames. You can then use your shell's command line editing to enter the rest of the command. Or if you are thinking ahead, you can type the command first then drag in the items.

The “drag first” version:

  1. Select and drag some Finder items to a Terminal window that is showing a shell prompt. Terminal will insert the (escaped) pathnames.
  2. Type Control+A (go to the beginning of the line; ⌃A is the default, but varies by shell/configuration).
  3. Type your command and a space (it will be inserted before the pathnames).

The “thinking ahead” version:

  1. In any order, do both:
    • In a Terminal window, type the initial part of your command and space (everything except the pathnames).
    • Select some items in Finder.
  2. Drag the selected items from Finder to the Terminal window where you typed the command.
  3. Activate the Terminal window and press Return.

You can (as other answers have indicated) turn to AppleScript or Automator if you need more a more automated solution. Since the extra “moving parts” can add some complexity to the solution, you will have to weigh the benefits of the above process (manual, but flexible) against the the complexity of implementing one or more of the automated solutions.

Some of the automation possibilities include:

  • an AppleScript droplet application
  • a plain AppleScript program launched by the built-in script menu or other launcher
    • get pathnames from Finder's selection
  • an Automator workflow, application, or Finder plug-in
  • an executable .command file (usually a shell script; open in Finder to run it in Terminal)
    • get pathnames from Finder's selection (via osascript)
  • some third-party tool that already provides the functionality you need
8

I don't think there is a way to do this directly. You can build an "Automator" application that will do some of what you are seeking. This shows what the Automator stack would look like:

enter image description here

Save the result as an Application, then in the finder select the files, right-click and select "Open with" then pick your application. (You may need to select "Other..." at the bottom of the application list.)

You don't get to interact with the script with this method, but you can loop over the files to perform some shell script.

1
  • It's even easier if you drag the files over the application icon, and drop them.
    – apaderno
    Jun 21, 2010 at 1:17
8

Services are how handles this sort of thing.

Under the Application Menu (in this case 'Finder') there is (almost) always a Services menu option which will provide Services that apply to the current Application and its current state. Typically the state is what type of object is selected (text, files/folders, etc).

They can be enabled, disabled, and assigned keyboard shortcuts in the System Preferences panel that only makes sense for the last of those three, Keyboard.

keyboard shortcuts

To make a Service that applies a shell script to files/folders in Finder:

Launch and make a new Service type document.

New Service

  • set the type of object the Service applies to (files or folders)
  • set the Application in which the Service is available ()
    • Alternatively there is a Get Selected Finder Items action.
  • add an action of Run Shell Script
  • decide if you want the input as arguments or

It should look something like this:

example shell script

will automatically place it in your ~/Library/Services folder when you save which will make it available (almost) immediately via the Application -> Services menu, or the contextual (right click) menu.

test folders

resulting TextEdit document

1
2

Based on the answers above, I built this thingy

https://github.com/commonpike/DropShell

Basicly an applescript app that calls a shellfile located in the app with the dropped files as arguments. You can modify the shell script as needed.

2

Based on commonpike's answer, I have created a AppleScript, that redirects all files dropped onto it, to a shell script with the matching name. Simply save as application from within Apple's ScriptEditor and rename as script.app to match your script.sh https://github.com/PHolker/scripts/blob/master/DropScript.scpt

1

In Mac OS X, the preferred script language is Applescript. You can create a droplet (a script that will do something when you drop some files over its icon), place the script (which can be saved as application) icon over the desktop, and drag and drop the files you want to pass to the script.

As alternative, you can use folder actions. It is possible to associate a script Applescript to a folder that will be executed all the times some files (or directories) are dropped over the folder.

1

I've been wanting to do that too, however unlike the solutions above, I wanted to produce quoted parameters for a shell script. Those other methods are fine, but they're kind of like suggesting "just command-v into terminal" when what you really want is pbpaste.

I wanted to make a shell function I can use in my scripts that expanded to file parameters for each Finder selection. I use the fish shell and this seems to work somewhat:

function selection
    osascript -e "tell application \"Finder\" to set s to the selection as alias list" -e "repeat with f in s" -e "set contents of f to POSIX path of f" -e "end repeat" -e "set AppleScript's text item delimiters to linefeed" -e "s as string"
end

Used (again in the fish shell) like convert-video (selection).

In a bash function, it might need to quote the output with something like | tr '\n' '\0' | xargs -0 printf "%q" {} on the end of that osascript command, not sure.

(note: everything i know about advanced applescript & shell scripting i re-learned in the past 2 hours and will forget by tomorrow)

1
  • Was trying to do this in bash recently, failed, asked on here superuser.com/questions/1353966, got answers that indicate: no, not possible :^( Bash you lose, gonna switch to fish shell on my work Mac also. Note that I do use the drag-to-finder trick mentioned by Chris Johnsen above, quite a lot. Aug 31, 2018 at 21:46
0

Since discovering FastScripts (which I highly recommend), I've been looking for a way to go all-in on it and rid myself of Automator. So I needed to have a way to pass the selected Finder items as parameters to the shell.

For that, I created a handler in my Applescript library Handlers.scpt in ~/Library/Script Libraries which returns the selection as POSIX or HFS paths, depending on the passed boolean.

on getselection(hfs as boolean)
    set text item delimiters to linefeed
    tell application "Finder" to set s to text items of (selection as text)
    if hfs then return s
    repeat with i in s
        set contents of i to POSIX path of i
    end repeat
    return s as text
end getselection

From my Bash script, I read the result of the handler to an array. The script exits when the first element in the array is empty.

#!/usr/local/bin/bash
mapfile -t i < <(osascript -e 'tell script "Handlers" to getselection(0)')
[[ $i ]] || exit 0

whatever-command "${i[@]}"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .