Section 13.5. Scripting


13.5. Scripting

In addition to Automator, Mac OS X has several scripting languages to help you automate tasks on your machine. At first glance, creating your own scripts may seem like a daunting task. The goal of this section is to take some of that dread away by introducing you to scripting in a friendly manner. There are some concepts that can

Figure 13-11. The Confidential Watermark workflow


be a bit hard to grasp at first, especially if you've never programmed before. But with a bit of luck and some know-how gained from the following sections, you'll be writing your own scripts in no time.

13.5.1. Scripting Languages

Picking a scripting language can be one of the most difficult parts of scripting, especially when you have as many choices as those supplied by Mac OS X. Sometimes, a certain language just works better for a job. For example, when you're working with text, Perl will prove much more versatile than AppleScript. It's the nature of the languageits included features and functionsthat helps you determine if it's up to the task.

Mac OS X comes with quite a few different scripting languages: Perl, Python, Ruby, AppleScript, C shells, Bourne shells...the list goes on. Some of these languages are much more sophisticated than others. Entire books have been dedicated to each, but in this chapter, we're just going to dabble with two: AppleScript and Bourne shell (that is, bash) scripting. These two languages are easier to grasp and flexible enough to accomplish a wide array of tasks.

13.5.2. Essential Programming Concepts

When you're writing a programand a script is really a small programthere are certain concepts that you'll frequently encounter. The terminology might seem a little strange at first, but once you understand what they do and when to use them, these concepts are applicable across languages.


Variables

Variables are perhaps the most basic idea you'll need to grasp. A variable is simply a placeholder for a value. The value might be hardcoded into the script when you write it, determined at runtime by some sort of process or equation, or by getting input from the user. Variables come in many different shapes and sizes, usually determined by the language you're using to write the script.


Operators and functions

The operators found in scripting are similar to those found in mathematics. Addition, subtraction, multiplication, and division are all operators that you're probably quite familiar with. Operators are a form of function. Functions are subroutinessmall blocks of code written for a specific purposethat return some sort of value after being processed.


Conditionals

A conditional is a comparative statement in code. The statement might compare two variables to each other, a variable against a specific value, whether a variable contains a value, etc. Conditionals usually take the form of if condition then action. Conditionals may also employ the else keyword, which will be processed if the conditional is not true. Another type of conditional is a case statement, where a condition is compared to several possible values with different actions.


Loops

Loops are blocks of code that are processed repetitively. Loops come in two main forms: incremental and conditional. In an incremental loop, the loop is processed a predetermined number of times. For example, a loop might use a counter that goes from zero to four, resulting in the loop code being processed five times. In a conditional loop, the loop code is processed until the desired condition is met.

Now that you're a little more familiar with the terminology, the following sections discuss how to put these concepts to practical use.

13.5.3. Shell Scripting

Chapter 4 discussed some of the basics behind shell scripts, but shell scripts can actually be quite complicated. The bash scripting language is pretty flexible, and there are a variety of command-line tools to help you accomplish just about any task. The major difference between scripting for the command line and scripting in an environment like AppleScript is that shell scripts are really just a bunch of commands saved in a file. The same commands that you enter at the command line can be strung together and saved for later use as a shell script.

The nice part about that is that it's easy to extend the commands available to your shell scripts by installing a few new tools. Take a look at Fink and DarwinPorts for some help; they're discussed in Chapter 2.


13.5.3.1. A simple script

To make a shell script, launch a basic text editor, such as nano, and kick things off with a shebang . "Shebang" is Unix parlance for a hash symbol (or number sign), followed by a bang (or exclamation point): #!. A shebang tells the shell which interpreter should be loaded to process the script. An interpreter is a program capable of processing the code found in the script. Conveniently, the interpreter for bash shell scripts is bash. So, the first line of any bash script you write should start with a shebang, followed by the path to the bash executable:

 #!/bin/bash

In programming circles, it's customary to have one's first program simply print "Hello, World! " to the screen. On the Unix command-line, there's a utility called echo that prints whatever arguments you supply it out to the screen. So, for our Hello World example, we need only two lines of code:

 #!/bin/bash echo 'Hello, World!'

Once you've typed these two lines of code into nano, press Control-O to save the file. Give it a name like HelloWorld.sh (The .sh extension will help you remember it's a shell script). After you've saved the file, press Control-X to exit nano and return to the command line.

You've just created a shell script. It might not be a particularly complicated shell script, but all of your future shell scripts will be created in a similar fashion. However, your shell script isn't quite ready to go yet. You must first set its execute bit, to indicate to the shell that the script is a valid command to be used on the command line. To set the execute bit on your script, use the chmod command:

 $ chmod +x HelloWorld.sh

Commenting and the Hash

Strangely, the first line of a shell script is only processed by the shell. To the script interpreter, a line starting with a # represents a comment. Everything after the hash symbol is ignored. It's a good idea to comment your scripts. As you grow more familiar with scripting, you'll find that the code is often self-explanatory. However, the logic behind your script may not be as obvious as its syntax. Some well-placed comments can help you remember what a block of code does when you need to revisit a script after a lengthy hiatus.


After its execute bit has been set, the script can be called like any other command. Because the script has been saved to your Home directory and not a directory that is in your shell's PATH, you must specify the absolute path to the script to run it, as shown in Example 13-1.

Example 13-1. Running the HelloWorld.sh script
 $ ./HelloWorld.sh Hello, World!

13.5.3.2. Tying in variables

Chapter 4 also discussed the concept of environment variables . If you recall, an environment variable is a value stored in memory that is used to set certain runtime parameters for shell commands. The variables found in scripts are used for similar purposes, with the exception that they only exist while the script is running and within the context of that script. Even though a script can view and manipulate environment variables, other scripts running in the same environment cannot see other scripts' variables. This is what is known as the scope of a variable.

To create a variable for your script, you must use an assignment statement. An assignment statement starts with the name of the variable you'd like to instantiate, an equals sign to indicate the assignment, and then the value you'd like to assign. For example, to assign the value "Hello, World!" to a variable named MESSAGE, use this statement:

 MESSAGE="Hello, World!"

The resulting variable, $MESSAGE, can be substituted for the original message in the HelloWorld.sh example. Remember that to use a variable, you must preface its name with a dollar sign. So, the HelloWorld.sh script rewritten to use a variable is:

 #!/bin/bash MESSAGE='Hello, World!' echo $MESSAGE

A nice thing about variables is that they can be assigned a value that is the result of a command (or series of commands). Using command substitution , you can call one command and have its results placed in a variable (or even used as a parameter for another command). Command substitution is processed using one of two code conventions. You can use either $(command) or `command` (note that a back tick is used, not a single quote). For example, to have the results of calling the whoami command placed in the variable ME, use the statement:

 ME=$(whoami)

The command is processed when the interpreter encounters your assignment statement, and the command results are placed in your variable. This variable can then be used just like any other. Expanding upon our HelloWorld.sh example:

 #!/bin/bash ME=$(whoami) MESSAGE="Hello, $ME!" echo $MESSAGE

The value from whoami can also be entered directly into the MESSAGE variable without assigning it to the ME variable:

 MESSAGE="Hello, $(whoami)!"

Or, you can skip the variables altogether:

 echo "Hello, $(whoami)!"

Single Quotes Versus Double Quotes

When you want to group several different words together as a single value, you should surround the words with quotation marks. Depending on if you use single quotes or double quotes, the shell will interpret the grouping differently. In the case of single quotes, the content is used in its literal form. For double quotes, the shell interacts with the content.

For example, echo "$PATH" (double quotes) will return the contents of your PATH environment variable. Entering the command echo '$PATH' (single quotes) simply prints $PATH to the screen without interpreting the PATH variable.


13.5.3.3. Conditionals in bash

Now that you know how to assign a value to a variable, you're probably wondering about ways to access that value. In most cases, you'll use a variable either in some form of output (like the echo statements discussed in the previous section) or in a conditional statement. As mentioned in the "Essential Programming Concepts" section, conditionals are used to perform an action based on the value of a condition.

When writing shell scripts, the most common type of conditional you'll use is the if statement. Using if statements, you can determine whether your desired condition evaluates to true. If it does, then the shell will follow the code until an else or fi statement is encountered. The else statement is used to define alternate actions that should be performed if your desired condition evaluates to false. Finally, the fi statement marks the end of the conditional logic. Example 13-2 shows a simple if statement.

Example 13-2. A block of conditional code
 if [ "$UID" == "0" ]; then   # It's true, do something as root   echo "You're root! " else   # It's false, the user is not root   echo "Sorry, you're not root. " fi

The other major conditional statement available in bash is the case statement. A case statement allows you to test a condition for several possible values. Each value has its own block of logic to be processed if the condition equals that value. A case statement starts out by calling case and supplying your condition, followed by the keyword in. Each possible outcome is then listed, with the potential value, the block of code to be processed, and two semicolons to mark the end of that value's code. Finally, the esac keyword marks the end of all of the case conditional logic.

Example 13-3 shows a case statement with three possible outcomes.

Example 13-3. A case statement with three potential outcomes
 case "$UID" in         0)      # The UID is 0, do something as root                 echo "You're root!"                 ;;         501)    # The UID is 501; the first user                 echo "You're the first user on this machine."                 ;;         *)      # Some other user                 echo "You're not root nor the first user."                 ;; esac

You might have noticed that the last potential value is an asterisk (*). In a case statement, the asterisk branch of code is used if the condition does not trigger one of the other code branches. The case statement is an excellent alternative to using nested blocks of if and else statements.

When creating a conditional, bash offers many different types of tests to perform. For example, you can check whether the value stored in a variable is equal to another value. You can check whether a file or directory exists. You can determine if you have read access to a file. These tests enable you to create scripts that react to a variety of different scenarios. Table 13-2 shows some of the more useful tests. To see what else is available, take a look at the manpage for test.

Table 13-2. Some useful bash tests

Test

Purpose

[ -a FILE ]

True if FILE exists

[ -d FILE ]

True if FILE is a directory

[ -r FILE ]

True if FILE is readable

[ -w FILE ]

True if FILE is writable

[ -x FILE ]

True if FILE is executable

[ -s FILE ]

True if FILE has a file size greater than zero

[ STRING1 == STRING2 ]

True if STRING1 and STRING2 are equal

[ STRING1 != STRING2 ]

True if STRING1 does not match STRING2


13.5.3.4. Send in the loops

Loops are where the real power of scripting comes into play. Being able to perform a series of commands on a series of files with just a few keystrokes can turn a tedious project into an easy job. Loops (and scripting in general) shift the burden of monotonous tasks onto the computer. As mentioned earlier, there are two types of programming loops. For incremental loops, bash uses the for command. For conditional looping, there are two options: while and until .

The bash shell handles for loops a bit differently from most other programming languages. It's still used for iterating through a block of code a certain number of times. The main difference, however, is that bash's for is designed to step through a series of values within a string. Chapter 4 provided an example of such a loop, which is repeated here in Example 13-4.

Example 13-4. A simple for loop
 for i in $(ls ~/Desktop/*.txt); do     say -f $i done

The earlier discussion of command substitution mentioned that the resulting value can be used as an argument for another command. That's exactly what's happening in Example 13-4. The ls command is run first, and its results are then supplied to the for loop. Example 13-5 applies the command substitution and shows what the resulting values might look like.

Example 13-5. The command substitution expanded
 for i in "/Users/jldera/Desktop/One.txt /Users/jldera/Desktop/Two.txt"; do     say -f $i done

The for loop then takes the first value from the list and inserts it into the variable i. The shell considers a blank space to be the demarcation between entries, so in the first iteration of the loop, i would have a value of /Users/jldera/Desktop/One.txt. Subsequent iterations of the loop step through the list of values until the entire list has been processed.

The other two loop commands, while and until, are based around the use of conditionals. They have a similar syntax, and both operate under the same basic principle. A conditional statement is checked and the loop either processes again or it doesn't. Depending on which command you're using, the when and why of stopping is handled differently. For the while command, the code inside the loop is processed as long as the condition holds true. Example 13-6 shows a while loop.

Example 13-6. T.G.I.F. while loop
 while [ $(date +%a) == "Fri" ]; do     # As long as it's Friday...     osascript -e 'say "T G I F"'     sleep 360 done

An until loop is the reverse. The loop code is processed while the condition is not true. Example 13-7 shows a simple until loop.

Example 13-7. An until loop
 # Use the shell's random number generator VALUE=$RANDOM until [ $VALUE -lt 1000 ]; do     # We do this til the value is less than 1k     echo Nope, $VALUE is greater than 1000.     VALUE=$RANDOM Done # Now print something after the loop is done echo Success! $VALUE is less than 1000.

13.5.3.5. Interacting with the user

Another important aspect of scripting is the ability to get parameter information and other feedback from the user. The read command and some special script environment variables are more than up to the task of supplying interaction with the user. When a script is launched, it has a few variables that are defined and populated with information about how the script was called. These variables can be used in your scripts just like any other variable. They just contain data that is supplied by the shell.

To get some information about the command-line execution of your script, look no further than the positional parameter variables. These variables start with the name of the script itself in position 0. Position 1 will contain the first parameter; position 2, the second; and so forth. You refer to the variable by using its numerical position, prefaced by a dollar sign. For example, the first parameter is $1. For positions beyond $9, enclose the number in curly brackets; e.g. ${13}.

There are a few other variables related to the positional parameters. The $* variable contains all of the position parameter values, combined into a single value. The $@ variable contains all of them as well, but the parameters are passed as individual values. Finally, the $# variable contains the number of command-line arguments that were supplied.

For those scripts that want more interaction with the user than command-line arguments offer, the bash shell includes the read command. Using read, the shell will wait for keyboard input from the user. Once the user presses Enter, the input is stored in the variable specified in the read call. For example, to get input from the user and store it in the variable AGE, use code like that in Example 13-8.

Example 13-8. Reading keyboard input
 echo -n "Please enter your age: " read AGE echo "Your age is $AGE!"

Getting Secure Input

If you're using the read command to solicit a password from the user, you should turn off the local echo of keyboard input. This prevents the user's password from being displayed on the screen and to any passers-by. To turn off the local echo, use read like this:

 stty_backup=$(stty -g) stty -echo read PASSWORD stty $stty_backup


13.5.3.6. Sample scripts

Nothing beats experience. If you haven't already, go back and try out some of the code examples. Most of them should work for you with fewif anychanges. The best way to learn to script is to jump in headfirst. Start out by trying a couple of little tests, even if they aren't practical. Even just working on redirecting output and piping when using the Terminal can help you build your scripting foo.

Here are a few scripts for you to pick apart and try out. Feel free to use them as a starting point for your own scripting efforts.

The script in Example 13-9 uses piping and the grep command to display information about a hard disk.

Example 13-9. Report essential information about a disk
 #!/bin/bash # disk_info.sh: Displays summary data about a disk DISK=/dev/disk0                     # The disk to check echo "Drive status for $DISK:" diskutil info $DISK | grep "SMART"  # Display SMART status echo; echo "Mount points:" mount | grep $DISK                  # Display mount points echo; echo "Disk Space:" df | head -n 1                      # Print out the column headers df | grep $DISK                     # Display only relevant results

Example 13-10 is a script that redirects the output from the system_profiler command into a file. It then uses the diff command to compare the output from the current run and output from the prior run. If a difference is found, it notifies the user and then displays the differences.

Example 13-10. Alert user to changes in system hardware
 #!/bin/bash # watch_profiler.sh: Alerts user if basic hardware is changed # Store the data from System Profiler temporarily system_profiler -detailLevel mini > /tmp/newest_system_profile # Check for changes if [ -f ~/.last_system_profile ]; then     DIFF=$(diff -s /tmp/newest_system_profile ~/.last_system_profile |          grep -c "identical")     # We have a change     if [ $DIFF == 0 ]; then         echo There have been changes to the hardware!         diff /tmp/newest_system_profile ~/.last_system_profile     fi fi # Setup for the next run mv /tmp/newest_system_profile ~/.last_system_profile

The script in Example 13-11 uses command substitution to get the current date, create a temporary directory using mktemp , and find out the directory path for a file. It also uses the find command to locate files that have been modified within the past day. After find's output is stored in a file, a while loop uses the read command to read the file back in. The results are then copied to the temporary folder, after which the hdiutil command is invoked to create a disk image of the workspace and place it on the desktop. Finally, the script removes its workspace to keep the disk clean.

Example 13-11. A simple backup script
 #!/bin/bash # daily_diskimage.sh: Creates a disk image of files found in #         FOLDER that have changed within the past day. #        The image is then placed in OUTDIR. FOLDER=~/Documents                           # The folder to search OUTDIR=~/Desktop                             # Where to place image TODAY=$(date +"%Y%m%d")                      # Get today's date WORK=$(mktemp -d /tmp/diskimage.XXXXXX)      # Create a work path find $FOLDER \( -mtime 1 -or -ctime 1 \) -and -type f \     -print >> $WORK/.BackupList              # Find files to backup # Copy our files to the work directory while read FILE; do     DEST="$WORK"$(dirname "$FILE")         mkdir -p "$DEST"     cp -v "$FILE" "$DEST" done<"$WORK/.BackupList" # Create a disk image of the work directory hdiutil create -fs HFS+ -srcfolder $WORK -volname $TODAY \     "$OUTDIR"/$TODAY.dmg # Remove our workspace rm -rf $WORK

As you can see, shell scripts can perform a variety of tasks and have a wide number of commands at their disposal. For more information on scripting, take a look at some of the books and manpages mentioned in the "Further Explorations" section at the end of this chapter.

13.5.4. AppleScript

Long before Mac OS X and its scriptable shell, the tool with which Mac power users automated their systems was AppleScript. AppleScript has persisted as a part of today's Mac OS, Tiger. In Tiger, AppleScript is still going strong, with more and more functionality and refinement being built into the language itself, its editor, and its interaction with the OS and user.

Commenting AppleScripts

For commenting in AppleScript, preface your comments with two hyphens (--). AppleScript also supports block commenting, which allows you to write lengthy comments easily. To use block commenting, start the block with (* and end it with *). You can use block commenting to disable a block of code for debugging purposes.


13.5.4.1. Another simple script

Unlike shell scripts, which are simply text files with a series of commands, AppleScripts have a special file format. So, to work with AppleScripts, you need to use a special editor, called Script Editor (/Applications/AppleScript), shown in Figure 13-12.

Figure 13-12. Script Editor


Much like shell scripts, the commands available to AppleScript are dependent on what software you have installed. When you install an application that supports AppleScriptwhich isn't all Mac applications, but many of themthe application implements an AppleScript dictionary . Using the app's dictionary, you can determine what kind of tasks you can perform in your script by calling that application. Figure 13-13 shows the Finder's dictionary.

To open an application's dictionary, open up Script Editor and click File Open Dictionary. A dialog box containing all of the available dictionaries will appear, allowing you to select the one youre interested in. You can keep as many dictionaries open as you'd like, which is convenient when you're looking up commands for multiple applications.

Figure 13-13. The Finder's AppleScript dictionary


Now that you're a little more familiar with AppleScript, its editor, and its dictionaries, let's take a look at its syntax. AppleScript is often described as a very verbose language. In their quest to make AppleScript more accessible to new users, Apple's developers made the language very English-like. This is both a blessing and a burden, as the code is far easier to read, but can be a bit more tedious to write. Example 13-12 is our Hello World script, revised for AppleScript.

Example 13-12. Hello World, AppleScript style
 display dialog "Hello, World!  "

Once you've entered that line of code into your script in Script Editor, click the Run button to execute it. A dialog like that shown in Figure 13-14 is displayed, letting you know it worked.

13.5.4.2. Variables: AppleScript style

Like any good scripting language, AppleScript has variables as well. AppleScript has more variable types than most shells, however, allowing you to store different types

Figure 13-14. The Hello World script in action


of values more efficiently. Assigning a variable in AppleScript is done using the set command, followed by the variable name, the keyword to, and then the value to assign to the variable. For example:

 set message to "Hello, World!"

assigns the value "Hello, World!" to the variable message. So, the Hello World script rewritten with a variable is:

 set message to "Hello, World!" display dialog message

Depending on the type of value you're storing and how you're going to use it, you can specify a variable type in its declaration. As an example, to declare the message variable as a string, use:

 set message to "Hello, World!" as string

You can also change a variable's type on the fly as follows:

 set num to 3 as number set message to (num as string) & " is a magic number." display dialog message

In addition to individual variables, variables can be combined into lists and records. A list is simply a series of values stored in a single list variable (often called an "array" in programming parlance). You can refer to individual items in the list, add items to the list, etc. For example, to create a new list, define it as follows:

 set animals to {"cat","dog","dogcow")

This line of code creates a new list named animals and populates it with three values. To refer to a specific item in the list, use the item...of keyword. For example, to refer to the second item in the list:

 display dialog item 2 of animals

The line above displays a dialog with the word "dog," which is the value stored in the second position of the animals list. To change a specific element in the list, use the item...of keyword in conjunction with the set command:

 set item 2 of animals to "horse" display dialog item 2 of animals

This time around, the resulting dialog displays the word "horse," since the first line has replaced the "dog" value in position two with "horse".

Records are quite similar to lists. The biggest difference between them is that a record stores multiple properties . Properties are essentially variables that have a persistent value. Most programmers would call such variables constants . Some properties are defined by an application (and thus listed in its dictionary). Others are user-defined using the property keyword, similar to using set.

The other unique quality of records is that their values are stored in name-value pairs. This allows you to then refer to a given property within a record by its name, instead of using a positional number. For example, here is a definition of a simple record:

 set pet to {name: "Charlie", owner: "Jason", type: "Turtle"}

Instead of using the item...of keyword, you'll want to refer to the property using its name. To get the owner property out of the pet record, use the statement:

 display dialog owner of pet

13.5.4.3. AppleScript conditionals

Also like the bash shell, AppleScript includes conditionals for diverting program logic. AppleScript has a variety of comparison operators, all of which can be easily used with an English-like syntax. Here are some example comparisons, each on a separate line:

 if type of pet is equal to "Turtle" then display dialog "Turtle!" if num is greater than 5 then display dialog "It's bigger than 5!" if passwd is not equal to "secret" then display dialog "Sorry, wrong password."

When working with strings, records, and lists, there are some special comparisons at your disposal. These comparisons make it easy to look for a specific substring or value. The starts with comparison is used to examine the beginning of a string. The reverse of starts with is the ends with comparison; use it to check the end of a string. Lastly, the contains comparison evaluates true when the substring is found within your variable. Here are some examples using these comparisons:

 if name of pet starts with "C" then display dialog "The name starts with a C" if animals ends with "dogcow" then display dialog "Clarus was here" if owner of pet contains "Jobs" then display dialog "Are you Steve's relative?"

13.5.4.4. Looping in AppleScript

In AppleScript, all loops are defined using the repeat keyword. Depending on whether you want the loop to be incremental or conditional, the syntax for using repeat is a little bit different. For example, to create an incremental loop in AppleScript, use code similar to Example 13-13.

Example 13-13. An incremental AppleScript loop
 set nums to "" repeat with i from 1 to 10     set nums to nums & " " & (i as string) end repeat display dialog nums

Like bash, there are two ways to use a conditional loop in AppleScript. Conveniently, the keyword and purpose for both types are the same as those found in the shell. Example 13-14 uses a while loop.

Example 13-14. A loop using while logic
 set today to the current date repeat while (today as string) starts with "Monday"     display dialog "Sounds like somebody's got a case of the Mondays"     set today to the current date end repeat

Example 13-15 shows a loop using until logic.

Example 13-15. Using until logic in a loop
 set WorldPeace to false as boolean         -- Sad, but true repeat until WorldPeace is equal to true     display dialog "All we are saying is, give peace a chance." end repeat

13.5.4.5. User interaction

AppleScript is much more flexible than shell scripts when it comes to interacting with the user. Though it is not possible to use parameters quite the way you would with a command line, it is possible to use several different dialog windows for soliciting information from the user.

In the previous code examples, the display dialog command has been used to provide feedback about a script's progress. This command can also be used to obtain basic text input from the user. For example, to get some text from the user and store it in a variable called nom, use this code:

 display dialog "Please enter your name" default answer "" set nom to text returned of the result

Since variables cannot have the same name as an AppleScript keyword, this example uses nom instead of name.


You can also give the user up to three different buttons to accompany the text input (or, just use the buttons for input and skip the text). To do this, use the buttons parameter of the display dialog command, as follows:

 set reply to display dialog "Enter pet's name and type" default answer "" buttons {"Dog", "Cat", "Turtle"} set nom to the text returned of reply set type to the button returned of reply display dialog nom & " is a " & type

If you want to offer the user more than three choices, you can use the choose command and implement a list. For example, to have the user choose an option from a list of fruits, use the command:

 choose from list {"apple", "orange", "pear", "banana"} with prompt "Pick one:" set fruit to the (result as string) display dialog fruit & "s are good"

The choose command offers several other dialog windows for different types of choices. The file keyword is used for files, folder for folders, and application for applications. As an example, you can have the user pick a file with the command:

 choose file with prompt "Pick a PDF file:" of type {"PDF"}

13.5.4.6. Sample scripts

Here are a couple of simple AppleScripts to help you get started on your own scripting projects.

Example 13-16 is an excellent candidate for a script to tie to iCal. The script activates iTunes and then plays a playlist named "Wake-Up." To use this script, create the playlist in iTunes and name it "Wake-Up." Populate the playlist with your desired tracks and then use this script as a musical alarm clock for iTunes.

Example 13-16. iTunes playlist script
 -- Opens up iTunes and plays a playlist named "Wake-Up" tell application "iTunes"     activate     play playlist "Wake-Up" end tell

Example 13-17 is an example of a folder action. Using folder actions, you can create a script that is launched upon changes to the folders contents. Example 13-17 displays a simple dialog window that notifies you when a file has been placed in a folder. This is a great script to use with your Mac's Drop Box. To configure the folder action, you'll first need to save your script in ~/Library/Scripts/Folder Action Scripts. Then, use the Folder Action Setup tool (/Applications/AppleScript) to select the folder to attach the script to, followed by your new script. Figure 13-15 shows a folder and its associated action scripts.

Example 13-17. A folder action
 -- Displays a simple dialog whenever a file is added to the folder on adding folder items to this_folder after receiving added_items     display dialog "Someone has placed an item in " & this_folder end adding folder items to

Figure 13-15. Configuring folder action scripts


13.5.5. Bridging the Gap

A convenient command for moving between the AppleScript and shell script worlds is osascript . Using osascript, you can execute an AppleScript from the command line, either by specifying the path to an existing script or using osascript's -e switch to enter the AppleScript line by line.

Example 13-18 is a script that will control iTunes playback.

Example 13-18. A script to control iTunes playback
 #!/bin/bash osascript - <<EOF tell application "iTunes"     playpause end tell EOF




Running Mac OS X Tiger
Running Mac OS X Tiger: A No-Compromise Power Users Guide to the Mac (Animal Guide)
ISBN: 0596009135
EAN: 2147483647
Year: 2004
Pages: 166

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net