- Table of Contents
- Copyright
- About the Author
- Acknowledgments
- Tell Us What You Think!
- Introduction
- Part I: Introduction to Mac OS X
- Chapter 1. Mac OS X Component Architecture
- Chapter 2. Installing Mac OS X
- Chapter 3. Mac OS X Basics
- Chapter 4. The Finder: Working with Files and Applications
- Chapter 5. Running Classic Mac OS Applications
- Part II: Inside Mac OS X
- Chapter 6. Native Utilities and Applications
- Chapter 7. Internet Communications
- Chapter 8. Installing Third-Party Applications
- Part III: User-Level OS X Configuration
- Chapter 9. Network Setup
- Chapter 10. Printer and Font Management
- Chapter 11. Additional System Components
- Part IV: Introduction to BSD Applications
- Chapter 12. Introducing the BSD Subsystem
- Chapter 13. Common Unix Shell Commands: File Operations
- Part V: Advanced Command-Line Concepts
- Chapter 14. Advanced Shell Concepts and Commands
- Chapter 15. Command-Line Applications and Application Suites
- Chapter 16. Command-Line Software Installation
- Chapter 17. Troubleshooting Software Installs, and Compiling and Debugging Manually
- Chapter 18. Advanced Unix Shell Use: Configuration and Programming (Shell Scripting)
- Part VI: Server/Network Administration
- Chapter 19. X Window System Applications
- Chapter 20. Command-Line Configuration and Administration
- Chapter 21. AppleScript
- Chapter 22. Perl Scripting and SQL Connectivity
- Chapter 23. File and Resource Sharing with NetInfo
- Chapter 24. User Management and Machine Clustering
- Chapter 25. FTP Serving
- Chapter 26. Remote Access and Administration
- Chapter 27. Web Serving
- Part VII: Server Health
- Chapter 28. Web Programming
- Chapter 29. Creating a Mail Server
- Chapter 30. Accessing and Serving a Windows Network
- Chapter 31. Server Security and Advanced Network Configuration
- Chapter 32. System Maintenance
- Appendix A. Command-Line Reference
- Appendix B. Administration Reference
Scripting Syntax
Describing the AppleScript syntax to a programmer familiar with C or Perl isn't as straightforward as you might think. AppleScript uses an entirely different programming model based on an English-like structure that, after a few minutes of use, will leave the programmer feeling as though he is having a deep, intellectual conversation with his computer.
tell
The basic building block of an AppleScript is the tell statement. tell is used to address an object and give it instructions to perform. A tell line is written in one of two common forms: a block or a single statement. The block format enables the programmer to send multiple commands to an application without stating its name each time.
Single:
tell <object> <object name> to <action>
Block:
tell
<object> <object name>
<action>
<action>
<action>
...
end tell
For example, the following two statements are identical, but are structured using the simple and block forms of tell:
tell application "Finder" to empty trash
and
tell application "Finder"
empty trash
end tell
Both of these short scripts will cause the Finder to empty the Trash can. Although the second form might seem more verbose, it is likely to be the most commonly encountered form. Most scripts interact with objects to perform complex compound operations rather than simple commands. In addition, the second version of the AppleScript is easier to read and view the functional components. Maintaining readable code is a good idea no matter what programming platform you're using.
Variables: set/get
In AppleScript, variables are automatically created when they are set. A variable name can be any combination of alphanumerics as long as the first character is a letter. There are no special prefixes required to denote a variable within the code.
Although type conversions happen automatically in many cases, a variable type can be explicitly given directly in the set statement:
set <variable/property> to <value> [as <object type>]
For example, both of the following lines set variables (thevalue and thevalue2) to 5, but the second line forces the variable to be a string:
set thevalue to 5 set thevalue2 to 5 as string
Variables can take on simple values, such as numbers or strings, or more complex values in the form of lists. Lists are equivalent to arrays in more traditional programming languages. A list is represented by a comma-separated group of values, enclosed in curly brackets {}. For example, the following line sets a variable, theposition, to a list containing two values:
set theposition to {50, 75}
This is often used to set coordinate pairs for manipulating onscreen objects, but can be comprised of any object. In fact, lists can even contain lists of lists. For example:
set thelistofpositions to {{50, 75} , {65, 45} , {25, 90}}
Here, a variable called thelistofpositions is set to a list of lists. Item 1 of the list is {50,75}, item 2 {65,45}, and so on.
In addition to setting variables, the set command can act on the properties of an object to effect changes on the system. Earlier you saw how an AppleScript could get the file type of a given file. Similarly, set can alter the file type. For example:
1: tell application "Finder" 2: set thisFile to (choose file with prompt "Pick the file to examine:") 3: set the file type of thisFile to "JOHN" 4: end tell
In line 3 of this code fragment, set is used to alter the file type of the chosen file to equal JOHN.
To retrieve values from variables, or properties from objects, you would use the get command. get, by itself, retrieves the value of an object or variable and stores it in the result variable:
get the <property/variable> [of <object>]
Traditional programmers might feel uncomfortable with retrieving results into a temporary variable (result); in that case, they can combine the get and set commands to immediately store the results of a get in another variable or object property:
set <variable/property> [of <object>] to get the <property/variable> [of <object>]
When dealing with list values, you can reference individual items within a list by referring to them as just that: items. For example, assume that you've run the following command:
set theposition to {50, 75}
To retrieve the value of the first item in the list, you can use
get item 1 of theposition
When dealing with lists within lists, just embed item statements within one another. Assume that this list has been entered
set thelistofpositions to {{50, 75} , {65, 45} , {25, 90}}
To retrieve the value of the second item of the second list within a list, you could write
get item 2 of item 2 of thelistofpositions
Again, the power of these commands is based in the dictionaries of AppleScript applications. With products such as FileMaker Pro, your AppleScript can edit, insert, and delete records.
If
A common programming construct is the If-then-else statement. This is used to check the value of an item, and then react appropriately. The syntax for a basic If statement is
If
<condition>
then
<action>
end if
For example, the following code asks the user to input a value, check to see whether it equals 5, and outputs an appropriate message if it does.
1: display dialog "Enter a number:" default answer "" 2: set thevalue to (text returned of the result) as integer 3: if thevalue = 5 then 4: display dialog "Five is my magic number." 5: end if
Line 1 displays a dialog prompt for a user to enter a value. Line 2 sets a variable thevalue to the text returned from the dialog, and forces it to be evaluated as an integer. Line 3 checks thevalue; if it is equal to the number 5, line 4 is executed. Line 4 displays an onscreen message, and line 5 ends the If statement.
The If statement can be expanded to include an else clause that is executed if the original condition is not met.
1: display dialog "Enter a number:" default answer "" 2: set thevalue to (text returned of the result) as integer 3: if thevalue = 5 then 4: display dialog "Five is my magic number." 5: else 6: display dialog "That is NOT my magic number." 7: end if
In this modified version of the code, line 6 contains an alternative message that will be displayed if the condition in line 3 is not met.
Finally, the else itself can be expanded to check alternative conditions using else if. This enables multiple possibilities to be evaluated within a single statement:
1: display dialog "Enter a number:" default answer "" 2: set thevalue to (text returned of the result) as integer 3: if thevalue = 5 then 4: display dialog "Five is my magic number." 5: else if thevalue = 3 then 6: display dialog "Three is a decent number too." 7: else 8: display dialog "I don't like that number." 7: end if
The latest version of the code includes an else if in line 5. If the initial comparison in line 3 fails, line 5 is evaluated. Finally, if line 5 fails, the else in line 8 is executed.
repeat
Another common programming construct is the loop. AppleScript uses a single-loop type to handle a variety of looping needs. The repeat statement has several different forms that cover while, until, and other types of traditional loops.
There are six different forms of the repeat statement:
-
Repeat Indefinitely—
Repeat a group of statements indefinitely, or until the exit command is called.
repeat <statements> end repeat
-
Repeat #—
Using the second loop format, the user can choose the number of times a loop repeats.
repeat <integer> times <statements> end repeat -
Repeat While—
Loop indefinitely while the given condition evaluates to true.
repeat while <condition> <statements> end repeat -
Repeat Until—
Loop indefinitely until the given condition evaluates to true. This is the inverse of the repeat while loop.
repeat until <condition> <statements> end repeat -
Repeat With—
Called a for/next loop in more traditional languages, this form of the repeat loop counts up or down from a starting number to an ending number. Each iteration updates a variable with the latest loop value.
repeat with <variable> from <starting integer> to <ending integer> [by <increment>] <statements> end repeat -
Repeat with List—
Like the standard repeat with style loop, the repeat with list loop runs over a range of values, storing each value in a named variable during the iterations of the loop. The difference is the value range is specified with a list, rather than an upper and lower integer value. This enables the loop to operate over anything from numbers to strings, to lists of lists.
repeat with <variable> in <list> <statements> end repeat
Subroutines
The final building block that we will cover in AppleScript is the subroutine. Subroutines help modularize code by breaking it into smaller, more manageable segments that can return specific results to a controlling piece of code. There are two types of subroutines in AppleScript: those with labeled parameters and those that use positional parameters. A parameter is a piece of information that is passed to a subroutine when it is called.
Positional parameters will be the most familiar to anyone who has used another programming language. This type of subroutine, which is the easiest to define and use, depends on being called with a certain number of parameters in a certain order.
Labeled parameters, on the other hand, rely on a set of named parameters and their values, which can be sent to the subroutine in any order. This can be used to create an English-like syntax, but adds a level of complexity when reading the code.
Because positional parameters can be used for almost any type of development and fit in with the structure of other languages discussed in this book, they will be the focus here.
The syntax of a positional parameter subroutine is shown here:
on
<subroutine name> ([<variable 1>,<variable 2>,<variable n>,...])
<statements>
[return
<result value>]
end <subroutine name>
Each positional parameter–based subroutine requires a name, a list of variables that will be supplied when called, and an optional value that will be returned to the main application. For example, the following BeAnnoying routine will take a string and a number as parameters, and then display a dialog box with the message. The display will be repeated until it matches the number given.
1: on BeAnnoying(theMessage, howAnnoying) 2: repeat howAnnoying times 3: display dialog theMessage 4: end repeat 5: end BeAnnoying
Line 1 declares the subroutine BeAnnoying and its two parameters: theMessage and howAnnoying. Line 2 starts a loop that repeats for the number of times set in the howA n noying variable. Line 3 displays a dialog box with the contents theMessage. Line 4 ends the loop, and line 5 ends the subroutine.
As expected, running this piece of code does absolutely nothing—it is a subroutine, and, as such, requires that another piece of code call it. To call this particular routine, you could use a line such as
BeAnnoying("Am I annoying yet?",3)
This will cause the subroutine to activate and display the message Am I annoying yet? three times.
A more useful subroutine is one that performs a calculation and returns a result. For example, the following example accepts, as input, an integer containing a person's age in years. It returns a result containing the given age in days.
1: on yearsToDays(theYears) 2: return theYears * 365 3: end yearsToDays
Because this subroutine returns a value, it can be called from within a set statement to store the result directly into a variable:
set dayAge to yearsToDays(90)
When working in subroutines, one must explicitly define variables that are only used in the subroutine, as opposed to those that can be accessed from anywhere in the AppleScript application. A variable that is visible to all portions of a script is called a global variable and is defined using the global declaration. Similarly, the local keyword can be used to limit the scope of a variable to only the code contained within a subroutine. For example, try executing the following AppleScript:
1: set theValue to 10 2: reset() 3: display dialog theValue 4: 5: on reset() 6: local theValue 7: set theValue to 0 8: end reset
In line 1, a variable called theValue is set to 10. In line 2, the reset subroutine is called, that appears to set the contents of theValue to zero. Yet, when the result is displayed in line 3, the original value remains. The reason for this strange behavior is the inclusion of line 6. Line 6 defines theValue as a local variable to the reset subroutine. This means that any changes to that variable will not extend outside of the subroutine.
To gain the behavior we expect (the contents of theValue are set to zero ev e rywhere), swap the local keyword with global:
1: set theValue to 10 2: reset() 3: display dialog theValue 4: 5: on reset() 6: global theValue 7: set theValue to 0 8: end reset
This tiny modification tells the reset subroutine that it should use the global representation of the variable theValue. When theValue is set to zero in line 7, it replaces the initial value set in line 1.
Other Sources of Information
AppleScript is a very capable language that offers many advanced features impossible to cover in the amount of space this title allows. What is provided here should be an ample start to creating scripts of your own and editing scripts included with Mac OS X. If you're interested in more information on advanced AppleScript syntax, I strongly suggest that you check the following resources:
- AppleScript Language Guide— http://developer.apple.com/techpubs/macos8/Interprocom/AppleScriptScripters/AppleScriptLangGuide/
- AppleScript Guide Book— www.apple.com/applescript/begin/pgs/begin_00.html
- AppleScript in Mac OS X— www.apple.com/applescript/MacOSX_Overview/index.htm
- AppleScript in a NutShell, Bruce W. Perry, ISBN: 1565928415, O'Reilly, 2001
Scripting Additions
Enterprising developers who open the power of their software to the AppleScript model constantly expand AppleScript. The most common type of scripting addition is a new application. Applications that you install under Mac OS X may or may not be scriptable—be sure to check the documentation or try opening the software's dictionary using the Script Editor.
In addition, some developers may deliver extensions to AppleScript in the form of a scripting extension. These extensions are not applications themselves, but libraries of additional functions that can be used in any AppleScript. There are currently very few AppleScript extensions compiled for Mac OS X, but, if you're interested, check out www.pasoftware.com/products/#AppleScript for a few examples of extensions.
Downloaded AppleScript extensions should be stored in ~/Library/ScriptingAdditions or the system-level directory /Library/ScriptingAdditions for access by all users.
Mac OS X Power Additions
An extremely useful addition for Mac OS X users who have decided to start shell scripting their applications are the OS X Power Additions found at www.vampiresoft.com/Products/MacOS/osxpoweraddos.html. These additions let AppleScript send commands directly to the Mac OS X Shell. For example, to return the results of the Unix command uptime, you could use the script:
return «event OSxaShel» "uptime"
Any command or Unix script can be run with the syntax:
return »event OsxaShel» "<unix command name>"
Users who are interested in working with only the GUI portion of Mac OS X might not be interested in this addition, but it is an invaluable extension for system administrators and Unix developers.
Script Runner | Next Section

Account Sign In
View your cart