In the previous lesson we created a bash script that runs a given command line in a new Terminal window. Now we'll see how to use Automator to make an instance of that available as a menu item in Finder.
Instructor: [0:00] In a previous lesson, we created term command, a script that runs a given command line in a new terminal window. A link to that lesson is in this lesson's description. I can say, "VI input.txt" to open the file in the current window. I can say, "term command VI input.txt" to open it in a new window.
[0:23] This term command vi app resembles a GUI app in that it opens in its own window. Naturally, it would be nice if we could open it with just the mouse. We can't do that just by clicking on an icon because we need to pass it one or more files to open.
[0:40] The natural thing to do would be to select the files in Finder. We'll use Apple's Automator to make the command available as a service in Finder. It's going to show up down here, where I already have a few other services available.
[0:54] Let's create it. We open Automator, which is found in the Applications folder. We're going to create a service, so we choose that. Automator is a drag-and-drop programming environment. This is the area where we build our app.
[1:12] First we configure it through these menus. It's going to receive files or folders from Finder.
[1:21] Then we're going to drag utilities run shell script into our pane. We configure this by saying it's going to receive input as arguments. Automator has pre-filled the shell script with the skeleton of a for-loop iterating over the arguments passed to the script.
[1:39] We'll replace echo $f with what we really want to do with each file. Finder passes the arguments as path names. We use the dear name and base name commands to extract the path and filename components of the path name.
[1:56] This here is called command substitution. Bash executes dear name in a subshell and replaces the command invocation with the standard output of the subshell. We're saving that output in a variable called dear.
[2:13] Then we CD to the directory where the file is and invoke term command by its full path name of wherever we have saved it on our computer. We surround file with quotes in case it contains a space. Since we're writing a script doubly nested inside other scripts, we not only have to escape the quotes with backslashes in order to pass them literally to the invoking script, but we also have to escape both the backslash and the quote with backslashes as well.
[2:46] Let's test our service right in Automator. We hit run. We get a warning.
[2:53] We get a warning because Automator can't open Finder for us. It's asking us to simulate Finder by using the Get Specified Finder Items action instead. We'll do that.
[3:05] We drag Files and Folders, Get Specified Finder Items into our pane to provide arguments for the shell script. The first thing I want to do is test it on a filename with a space, such as "two words.txt."
[3:24] Now I hit run. We get the warning again, but we can ignore it this time. Yes, it works.
[3:37] Let's test it on two files. Run it again. Ignore the warning again. Each file is opened in its own window.
[3:58] We're reasonably satisfied that our service works properly. We remove our test harness here, Get Specified Finder Items. We go to the menu to save it.
[4:11] We give it a name, Open With VI. We can quit Automator and return to our Finder window, where we find that the Services menu now contains an Open With VI action. The service that we created is located in your Home Directory/Library/Services, from which we can delete it if we're tired of it and don't want to use it anymore.
[4:46] If you use a service frequently, it's a bit of a pain to navigate the menus like this. We can assign a keyboard shortcut to it. For this purpose, we go to the Finder menu, Services, Services Preferences.
[5:03] We find our service. Files and Folders, Open With VI. We add shortcut. I'm just going to choose command-zero. Now that I've done that, I go back to my Finder window. I select a file. I just hit command-zero and it works again.