How to build Mac OS X services with Automator and shell scripting

In this hands-on tutorial, Ars will show you how to use Automator to build …

I recently switched to Mac OS X as my primary desktop operating system after spending over a decade on Linux. Although Apple's operating system supplies practically all of the command line tools I know and love, I want to spend less time in a terminal window and start cultivating workflows that integrate better with the Mac user experience.

In my quest to tear the power of the command line out of the terminal, I have found that Apple's Automator tool is a powerful ally. Although it's not as mighty as the command line for improvisational automation, it's useful for defining stand-alone operations that you want to be able to repeat. I've used Automator over the past week to build simple applications that replace some of my personal shell scripts.

One of the most compelling features of Automator is support for building services—headless applications that are pervasively accessible throughout the operating system. Many services are context-sensitive and designed to process or operate on user input. A brief and unscientific poll of Mac enthusiasts revealed that few actually use the Services menu. Despite its relative obscurity among users, I've learned to appreciate its value.

Apple offers a number of its own services—like one that supports dictionary lookup on a selected word—that work with the platform's standard applications. Third-party developers can also create services to deploy with their applications. Automator makes it really easy for regular end users to create their own services with specialized behaviors.

As a Linux refugee, one of the features that makes Automator particularly compelling is that it allows me to integrate command-line operations, commands, and pipelines into my Automator workflows. In this tutorial, I'm going to show you two of the ways that I use shell scripting in Automator services in order to simplify my work.

A trivial example

I write virtually all of my articles in the Vim text editor and use Markdown syntax for formatting. On Linux, I used a Markdown processing tool from the command-line to convert my articles to HTML and then piped the output into the xclip command so that I could just paste the finished article directly into Ars Technica's content management system. I had a simple shell script that I could call directly from within Vim itself to perform those steps.

This same approach is still viable on Mac OS X, but I wanted to explore a more Mac-native solution to the same problem. More importantly, I wanted a solution that wasn't tied solely to Vim. That's where Automator comes into play. I built a trivial service that wraps a command-line Markdown processor. I can select a block of editable text with Markdown formatting in any Mac application and use the Markdown service to convert it to HTML in place.

To create a service, you start by selecting New from Automator's File menu. Automator will show you a list of available templates and prompt you to choose one for your new project. You should select the Service option, which is accompanied by a gear icon. In your new service, you will see a bar at the top of the Automator flow pane. It has combo boxes that allow you to set filters that establish the conditions in which your service should be made accessible. You want to make a service that receives selected text and will operate in any application.

Below those combo boxes is a checkbox that you can toggle to specify whether you want the output of your service to replace the selected text block. We definitely want that to be checked for our Markdown service, because we are replacing the Markdown-formatted input text with the HTML output provided by the Markdown processing engine.

The behavior of our Markdown workflow is really simple, so it will only require one action. From the left-hand action library pane, drag the Run Shell Script action out into the workflow pane. It will automatically create a connection with the top bar, indicating that it will use the user's selected text as the initial input.

The shell script action has a few simple options. You can choose the shell environment that you want to use for the operation and you can choose how you want it to handle the input. For the purpose of this example, we want to use the standard Bash shell. We also want to configure the action to pass the input into stdin, the UNIX standard input stream. This is a really useful capability in Automator, because it makes it possible to seamlessly mix Automator workflows with shell pipelines.

In the main text area of the shell action, we need to specify what command-line expression we want Bash to execute. In this case, all we want it to do is run the markdown command. I have already installed the markdown command using the relevant Homebrew package, but Automator's Bash shell doesn't seem to find it in my command path. To work around Automator's difficulty finding the command, I simply put the full path into the text box, as you can see below.

Now that the workflow is complete, you just have to save it under the name Markdown. By default, Automator will store your custom services in the ~/Library/services directory. Any Automator service that is copied into that path will be made available through the services menu under applicable conditions. To run the new service, you just have to select some text and then click the Markdown item in the services menu.

There are a number of ways that you can customize this service to achieve alternate behaviors. For example, you could use the Copy to Clipboard action at the end of the workflow to make the output go to the user's clipboard rather than replacing the selected text.

52 Reader Comments

Automator is weird and AppleScript is positively alien. Probably my biggest issue with Automator is that it has a tendency to keep running workflows when you don't want it to because something should have failed further up the chain.

Whilst not a service, I use one of its folder actions for my little Mac mini web dev server that sits downstairs. I do a rotating off-site backup using Time Machine, but because TM doesn't natively support two HDDs I have a folder action set up to watch the /Volumes folder, and to then determine which drive has been plugged in and change the Time Machine settings to use it. One nice bonus is that after it's run, the Mac mini starts immediately synchronising all the changes that the HDD needs to catch up on. Then, because it's a headless computer, it speaks which drive it has found once successful.

But it wasn't easy to set up. In fact, the pure simplicity of Automator actually made doing something relatively simple (figure out which HDD is in, do an action based on this result) relatively difficult. It works, though, so I guess that's a win.

Who knows if Apple is going to keep Automator though... it's hardly been touched since Tiger.

Thanks for reminding me that despite my 15+ years using dozens and dozens of makes and models of computers and despite my current ownership of 5 computers, two cell phones, 6 MP3 players, a tablet computer, and an eReader... I'm still a total noob.

I have no idea why I would need to even begin to learn how to use automator. That makes me a little sad!

Apple has been increasingly hostile towards any kind of scripting and automation in iOS. Sadly, looking at the total lack of interest things like Automator in OS X receive from the users Apple seems to be not totally wrong in just leaving anything like this out in iOS.

To be honest, I use lots of shell scripts on OS X but my few tries with Automator invariably lead to nothing. Writing plain sh scripts and using them in a terminal is so much simpler and more straightforward that fighting the Automator UI seems just a waste of time. It's somehow cool in places, but usually totally not worth the effort.

A few additions sure (and perhaps I was being a bit glib there and should instead have written Leopard), but I just get the feeling, especially from Leopard -> Snow Leopard and possibly even to Lion that Automator is kinda there, but could be removed if Apple so deigns. It was a heavily touted feature of Tiger and sure, it got a bit of a fiddle with Leopard. But I'm thinking that despite its outward "friendliness" that people in general may not be using it as much to justify its existence or engineering expense.

It's just a hunch though. I hardly think we'll be seeing "new Automator features" as something that will feature prominently - if at all - in Lion.

To me the biggest innovation in Snow Leopard was how significant an upgrade Automator and Services got. You can assign any Automator script a menu and custom command key. I think that for speed you're still better off getting a program like Quickeys to run common scripts.

There are a ton of standard Automator functions you can use but the real power comes by using Python or Ruby. Throw in Appscript which gives Applescript capabilities with a far better programming language and you have a ton of power. I do 95% of my scripting in Python and it really is amazingly powerful. I have, for instance, a script that turns any selected address into a FedEx mailing slip. Plus tons more.

Applescript as a language is horrible to program in but the capabilities really are great. Replace Applescript the language with Python and you have something remarkably powerful.

I still have my copy of "The Tao of AppleScript" gracing a shelf in my office. Can't say I've coded a line of it since I ran System 7.4, but it was a nifty language at the time. Maybe I need to steal the wife's MBP and play around with it again.

I recently switched to Mac OS X as my primary desktop operating system after spending over a decade on Linux.

Somewhat OT for the topic of this thread, but a write-up on the reasons for the switch would be very interesting ie what would lead a long-term linux user with significant involvement in the platform to move to an alternative which is technically quite similar but philosophically very different?

Interesting article and a good opportunity for me to ask for help. From time to time I get mails where something has gone wrong with encoding of the attachment. Instead of an attached file I get plain text which I then have to copy/paste into a new file and the decde in the shell with "openssl base64 -d -in <infile> -out <outfile>".

I now tried to turn this into a service, but so far I was unable to turn the selected text into an argument for the Terminal command. Hints welcome.

Create a new serviceAt the top right, service receives selected "text" in "any application"Under utilities, drag "run shell script" over as the only action in the workflow, choose to pass input as "arguments"In the code area, you can test with:

Code:

for f in "$@"do echo "$f" > /tmp/testdone

Save the service.

Open up an app with selectable text, right click, look at the bottom of your menu. You should see the name of your service. Click it.Go check the contents of /tmp/test. Should be what you selected.

I recently switched to Mac OS X as my primary desktop operating system after spending over a decade on Linux.

Somewhat OT for the topic of this thread, but a write-up on the reasons for the switch would be very interesting ie what would lead a long-term linux user with significant involvement in the platform to move to an alternative which is technically quite similar but philosophically very different?

I did the same thing as the author several years ago. The primary reason: a cohesive GUI desktop environment built on a UNIX OS.

I prefer Gnome to KDE (sticking to the two major DEs). So I would try to use GTK+ based programs over QT based programs. At the time, and this may have changed by now, the only decent optical writing software was K3B. So if I wanted to burn a CD, I would have to use a KDE program from within Gnome, and that's just ugly. This is just one example for illustrative purposes.

The point being, applications written for the same environment tend to follow the same design principles. Therefore, the user experience remains consistent and the user doesn't have to "switch modes" depending on which program he is running at the time.

Additionally, I like that I don't have to get so intimate with the maintenance of desktop OS. I install the updates when they are available (and I feel like installing them) and that is about it. In Linux, the chances are pretty good that I will have to, at some point, dig down into the X config or similar. I just want my desktop to work.

I think the reason I've not jumped into the world of automator actions above and beyond some simple photo post-processing actions is because debugging them is so damn tedious. If the automator gui did a better job of showing you what is going on, it would be much less time consuming to use. I think most folks who use automator actions just have a directory with their shell/perl/python scripts and use services as convenient ways to call them with some data on STDIN.

There's a StackOverflow answer for this (http://stackoverflow.com/questions/1356 ... es-in-os-x) but I wouldn't take their suggestion of using /etc/launchd.conf. It's not the accepted method for doing what you want - they chose it because there was a bug in OS/X prior to Snow Leopard that sometimes ignored environment.plist during application launching. You're better off with environment.plist and much less likely to lose settings during OS/X upgrades.

I'd be curious as well why the author switched (especially given his involvement with the Linux community). I was never nearly as accomplished with Linux, but I moved my primary desktop over to Windows 7 a few months ago - not having random things break when Canonical shipped a new (beta-quality) release was a big incentive (I'm not picking on Canonical - Ubuntu seemed to have better hardware support than the other distros I tried). That said, finding Cygwin made my week - I like Win7, but it lacks a proper terminal environment.

I have to say I'm surprised so many people have been saying Automator hasn't received much attention. It received some huge upgrades with Snow Leopard giving it new features. These were featured prominently in Apple's Snow Leopard pages. Automator got with 10.6 the ability to generate Services making that feature from NeXTStep extremely useful. There was a new control panel to let you quickly turn on or off Services. In addition to Services in Automator you could create print plugins (those options in the print menu) and a lot else. They also added quite a few new Automator actions.

Now when it comes to Applescript proper, I'll agree with you. It hasn't had a lot of love from Apple for a while. Apple did introduce the Scripting Bridge for Obj-C, Python and Ruby. But it was (IMO) inferior to Appscript and has quite a few limitations. Apple's own apps (especially Mail and Numbers) aren't nearly as scriptable as they should be. I attribute at least some of this to allocating resources to iOS.

Lion doesn't appear to offer much with respect to Applescript or Automator that I can see. Unlike Snow Leopard. (There appear to be a few new actions primarily tied to the new QT, but that's it) Still I'm hoping to hear more at WWDC.

I've used Services to do things like convert png screenshots to jpegs with a right click, amongst other things. Very, very handy.

But don't stop with Automator. Applescript supports terminal commands as well, as well as QuicKeys. (http://startly.com/ I have no connection to Startly other than a happy user.) QuicKeys has been in the toolbox of many Mac power users since the 90s. It can contain Applescripts in it's actions, and it can directly issue terminal commands to OS X as well. Giving you push-button access to those commands, no matter how complex. It is another memory eater for sure, but worth it if you ask me. I use it to do lots of things. Past text into fields, control Photoshop, log my hours into Peoplesoft, etc.

But Applescript is the crown jewels of Mac automation. And there's two books that will get you deep into it quickly. Sal Soghoian's book "Applescript 1-2-3" is a bargain considering how it gets you up to speed in record time. Sal is the guy in charge of Applescript at Apple. And then follow that with Matt Neuberg's book "Applescript The Definitive Guide" which is the top reference for everything Applescript outside of Apple's own documentation.

Add to that a phenomenal script editor, Script Debugger by Latenight software (very expensive, but worth every penny) which lets you see inside applications as they are running and give you references to objects in those applications to address with your scripts, and you have a killer combination for automation that can't be beat.

I've used Script Debugger to automate Applescript to control Extensis Portfolio, Filemaker Pro, Photoshop and other applications, to make me vastly more productive as a photo editor for an international non-profit research and educational institution where three photo editors used to do the job.

Hope this doesn't sound like spam. But I wanted to welcome you to the world of OS X automation and point out some directions you might want to go.

I'd second the value of Quickeys. I'd used it way back in the Sys7 days but hadn't used it with OSX due to its high price. The price has come down and the UI is greatly improved. I'd been using iKey for the past few years but switched last week and am pretty glad I did. You can use Automator + Services to assign any script to a key command. But Automator is slow - it's one big downside. A macro program like Quickeys or FastScripts can really speed this up. Quickeys is probably the nicest simply because it does so much more. But if you just want to assign keys then iKey or Fastscripts is the way to go.

To add to the above comments one very nice thing you can do with Applescript is GUI scripting - i.e. hitting buttons and the like. Unfortunately this is a bit of a black art for anything complex. Apple has an application GUI Inspector to list the names of objects. But it's a pain to use and a third party app like UI Browser is better, albeit hard to justify for casual scripting.

Tons more ( http://grab.by/grabs/87f5e38b8fad56720f ... 85ab94.png ). This shit is magic and when OnMyCommand was broken by 10.6, I was so happy to find out how to do this with Automator. Apple's creation of *nix apps like pbpaste, pbcopy, open, etc. really make this a great bridge between the GUI and shell.

I need to update it to work with multiple selected files as input (you currently have to add them to the queue one by one). If you want to try changing it yourself, the general way to do this is to use stdin as the input and do this type of thing:

I recently switched to Mac OS X as my primary desktop operating system after spending over a decade on Linux.

Somewhat OT for the topic of this thread, but a write-up on the reasons for the switch would be very interesting ie what would lead a long-term linux user with significant involvement in the platform to move to an alternative which is technically quite similar but philosophically very different?

I'm a similar switcher.

When it comes down to it, IMHO the biggest thing is keeping up with the update/innovation cycle, and the lack of support for commercial linux applications. I like firing up photoshop, then switching to a shell window to have my unixy stuff, and then firing up X apps as warranted nearly-natively.

Freedom is good, but having stuff is also. Strict GNU-everywhere is stupid.

Wow, it's amazing how much the common perceptions about automation in Mac OS X differ from reality!

All Mac OS X automation technologies received a major upgrade in Snow Leopard, especially Automator. Mac OS X 10.6 introduced Automator services, and AppleScriptObjective-C. AppleScript apps now have direct access to the Cocoa frameworks and their UI can use standard outlets, actions, and bindings!!!!!!!!!!!!

When AppleScript was first introduced during the System 7.x flows, it was hopelessly slow, and supported practically nothing. At the time I believed both of these problems were related... The AppleEvent object model required extensive decoding and often a redesign of the entire application ("factoring" as they called it), and even Apple's own tools didn't bake-in support. On the speed side, under the co-op tasking model, every command/response requires several context switches.

When OSX was forming, I was excited because I knew that the model under OpenStep would directly support AS for most apps out of the box. And with a true OO messaging system, the overhead would be greatly reduced.

Then I got a job at a PC shop, and did everything with VBA and Office. And it rocked. Totally.

So my question: is AS still as sucky and slow as ever? Or should I put some time into AS and Numbers/Pages?

Numbers has very poor Applescript support. Most of us expected an iWork update months ago to resolve this. But it looks like Apple had taken many people off such projects to finish iOS. It now appears the iWork update is awaiting Lion so it can leverage Lion's built in versioning features. So expect it this summer. Pages has much better Applescript support for everything except tables.

Applescript as a language is horrific. It's what some joke is a read only language (as opposed to write only languages like Perl or Awk) It's very easy to understand or modify an existing Applescript program but a royal pain to write your own for anything not short. Trying to to text processing in Applescript in particular is a nightmare. For that reason almost everyone serious downloads Appscript which adds native Apple Events and Dictionary support to Python, Ruby and Obj-C. It's very nice and elegant and comes with a translator that translates Applescript to Python or whatever. The advantage is you then get the speed and features of each of those languages. This makes Applescript much more akin to what you can do in Visual Basic on Windows with the advantage that many more applications support Applescript on OSX than appear to support VB scripting on Windows.

I know I should put some time into learning it, but every time I open automator or applescript, I can't seem to do what I want. My current wish is to make a service that converts selected text in any application to a new note in notational velocity. Not sure if this is possible without scripting but any help is appreciated!

Wow, it's amazing how much the common perceptions about automation in Mac OS X differ from reality!

All Mac OS X automation technologies received a major upgrade in Snow Leopard, especially Automator. Mac OS X 10.6 introduced Automator services, and AppleScriptObjective-C. AppleScript apps now have direct access to the Cocoa frameworks and their UI can use standard outlets, actions, and bindings!!!!!!!!!!!!