[ Team LiB ] |
2.7 UnixBy the term Unix I mean the command line and other shell-related environments such as Perl and Ruby scripts. Here the important word to know is osascript. This verb is your key to leaping the gulf between Unix and AppleScript. You should read the relevant manpages. (Further details are provided in Chapter 23.) osascript can execute a compiled script file or can compile and execute a string. The option -e signals that it's a string, not a script file, and of course if you're going to type a literal string, this raises all the usual problems of escaped characters. In the Terminal you can usually bypass these problems by single-quoting the string. The following little conversation in the Terminal illustrates the difference in the formatting of the output depending on whether you supply the -ss flag. I generally prefer this because it does a better job of showing you what sort of reply you've really got. The curly braces and the double quotes show clearly that it's a list of strings: $ osascript -e 'tell app "Finder" to get name of every disk' xxx, main, second, extra $ osascript -ss -e 'tell app "Finder" to get name of every disk' {"xxx", "main", "second", "extra"} In a Perl script it's rather easy to tie oneself in knots escaping characters appropriately so as to construct the correct string and hand it off to osascript. The difficulties are even worse than in the Microsoft Word example earlier in this chapter, because two environments, Perl and the shell, are going to munge this string before it gets to AppleScript. This line of Perl shows what I mean: $s = `osascript -e "tell app \\"Finder\\" to get name of every disk"`; The Perl backtick operator hands its contents over to the shell for execution, but first there's a round of variable interpolation within Perl; during that round, the escaped backslashes are mutated into single backslashes, and these single backslashes correctly escape the double quotes around "Finder" in the string that the shell receives as the argument to osascript. (Obviously I could have single-quoted that string and avoided the backslashes, but that wouldn't have illustrated the problem so well.) A more humane approach—and much more common because it allows you to construct multilined, legibly formatted AppleScript code easily—is to take advantage of your language's "here document" facility and do your variable interpolation there. You then hand the AppleScript code to the shell, single-quoted. By way of illustration, here's a rather silly Perl program intended to be run in the Terminal; it asks the user for the number of a disk and then fetches the name of that disk: #!/usr/bin/perl $s = <<"END_S"; tell application "Finder" count disks end tell END_S chomp ($numDisks = `osascript -ss -e '$s'`); print "You have $numDisks disks.\n", "Which one would you like to know the name of?\n", "Type a number between 1 and $numDisks: "; while (<>) { chomp; last if $_ < 1 || $_ > $numDisks; $ss = <<"END_SS"; tell application "Finder" get name of disk $_ end tell END_SS print `osascript -ss -e '$ss'`, "Type a number between 1 and $numDisks: "; } Observe that the result of osascript has an extra return character appended to it, which has to be chomped if that isn't what we wanted. Here's the game in action, played in the Terminal: $ ./disker.pl You have 7 disks. Which one would you like to know the name of? Type a number between 1 and 7: 3 "xxx" Type a number between 1 and 7: 4 "second" Type a number between 1 and 7: bye Communication in the reverse direction, calling the shell from AppleScript, is handled through the do shell script command, which is dealt with in Chapter 23. |
[ Team LiB ] |