Run shell scripts from the macOS Services menu

By Michael Argentini
Managing Partner, Technology and Design

If you're a macOS/OS X developer and use Terminal utilities like Sass or Compass, I've created a simple way to launch them from bash files without having to manage permissions or even launch the Terminal. It's a real time-saver!

Let's take Compass as an example. First, create your Compass bash script using a text editor.

compass watch -c config.rb templates/scss/style.scss

This is a one-line command to launch Compass and watch the file (and dependencies for) "style.scss". Save this as something like "watch.sh".

Next, in Automator, create a "Service". Add the "Run Applescript" action. At the top, for "Service receives selected" choose "files or folders". Then paste the code below into the Applescript window.

Note: you will have to convert the curly apostrophes to standard ones.

on run {input, parameters}

    set winnum to 1

    repeat with f in input

        set default_delimiters to AppleScript’s text item delimiters

        -- If given file is a folder strip trailing ":" to return 
        -- folder name as file name and parent directory
        if last item of (f as string) = ":" then
            set AppleScript’s text item delimiters to ""
            set input to (items 1 through -2 of (f as string)) as string
        end if

        set AppleScript’s text item delimiters to ":"
        set this_parent_dir to (text items 1 through -2 of (f as string)) as string
        set this_name to (text item -1 of (f as string)) as string

        -- default or no extension is empty string
        set this_extension to ""

        if this_name contains "." then
            set AppleScript’s text item delimiters to "."
            set this_extension to the last text item of this_name
            set this_name to (text items 1 through -2 of this_name) as string
        end if

        set AppleScript’s text item delimiters to default_delimiters    
        set AppleScript’s text item delimiters to the ":"
        set the item_list to every text item of this_parent_dir
        set AppleScript’s text item delimiters to the "/"
        set this_parent_dir to the item_list as string
        set AppleScript’s text item delimiters to ""

        tell application "Terminal"

            activate

            if winnum is 1 then

                do script with command "cd \"/Volumes/" & this_parent_dir & "\";sh \"" & this_name & "." & this_extension & "\"" in window 1

                set winnum to 2

            else

                do script with command "cd \"/Volumes/" & this_parent_dir & "\";sh \"" & this_name & "." & this_extension & "\""

            end if

        end tell

    end repeat

end run

Save and give it a name for the Finder's Services context menu, like "Execute Shell Scripts". Now, when you navigate to the file "watch.sh" and right-click it, you can navigate to the "Services" menu and find your script. Click it and watch Terminal fire up and launch your script.

Multiple Scripts

This solution supports multiple files. So if you select two or more ".sh" files and execute them, it will launch separate windows for each of them. In my case this comes in handy when I want to run Compass for compiling CSS into a templates directory, as well as a second time to compile it into the web application project directory.

Article last updated on 4/21/2018