AppleScript Primer for Mac OS X
Pages: 1, 2
Hello Unix Shell
AppleScripters can use the Unix shell in two different ways with Mac OS X 10.1.2. The "do shell script" command executes a Unix shell statement without having to target a specific application. For example, type the following script into a Script Editor window, then compile and run it. It will issue three Unix shell commands, each separated by a semi-colon.
do shell script "cd $HOME; pwd; ls -l"
The script then receives the return value as a string (a bunch of characters, like a written sentence, surrounded by quote marks), which it can then process as needed. Here is a portion of the return value of the latter script:
"/Users/brucep
total 0
drwxr-xr-x 7 brucep staff 264 Nov 24 20:27 AllProps
drwxr-xr-x 5 brucep staff 126 Jan 4 19:57 Applications
drwx------ 17 brucep staff 534 Jan 18 10:24 Desktop
drwx------ 14 brucep staff 432 Jan 18 10:17 Documents
..."
Scripting Terminal
You can also script the Terminal application, which is the command-line utility installed with Mac OS X. The following script will open up a new Terminal window and launch the Apache Tomcat Java servlet engine and MySQL database server. Very useful!
ignoring application responses
tell application "Terminal"
activate
do script with command ¬
"/Users/brucep/bin/start_tomcat; /usr/local/bin/safe_mysqld &;"
end tell
end ignoring
The "¬" character, a line-continuation character, is produced on the Mac by typing option:return. The "ignoring application responses/end ignoring" block will prevent the AppleScript from stalling while it waits for a response from Terminal. One source of more information on the "ignoring" AppleScript statement is on page 137 of my book, AppleScript in a Nutshell.
Sidebar: Scripting ITunes 2
Here is a script that opens up iTunes 2 and lets the user choose a song by its title, then plays the song.
tell application "iTunes"
activate
try
set mainWindow to item 1 of browser windows
set _playlist to the view of mainWindow
set theSongs to the name of every track of _playlist
set songTitle to ¬
choose from list theSongs with prompt ¬
"Choose a song to play"
tell _playlist
set song to item 1 of ¬
(every track whose name contains the songTitle)
end tell
say "Now playing the song " & (name of song) & ¬
" by " & (artist of song)
play song
on error
display dialog ¬
"Either a playlist is not selected or you canceled the dialog.
Please try again."
end try
end tell
This script displays all the song titles for the tracks that are contained by iTune's main window. The user can then select a song title from a list that appears in a dialog window (the script part "choose from list theSongs" produces this song-filled dialog). The “say” AppleScript command will cause the computer to speak whatever phrase you feed to the command. The voice for this command is configured in Mac OS X's Speech preferences, which is found in the System Preferences window. You can even use “embedded speech commands” to modify how the “say” AppleScript command reads the text. See pg. 393 of “AppleScript In A Nutshell” for more information on embedded speech commands.
Web Services
Web services are XML applications that exchange focused bits of information between distant computers. These services include two protocols: XML-Remote Procedure Call (XML-RPC) and Simple Object Access Protocol (SOAP). Without getting too deeply into the technical stuff, both of these protocols use Hypertext Transfer Protocol (HTTP), the same data-transfer method as the Internet, to send and receive information remotely. Both the requests and the responses in XML-RPC and SOAP are formatted as XML. AppleScript on Mac OS X 10.1.2 makes it easy to use both XML-RPC and SOAP.
Callxmlrpc
Starting with Mac OS X 10.1, scripters can use the "call xmlrpc" command. You begin by targeting an XML-RPC server in a "tell" AppleScript block. The following script queries an XML-RPC server at "http://time.xmlrpc.com/RPC2" for the date and time. It's just a simple example; there are numerous other types of data that are accessible from SOAP and XML-RPC servers. The "call xmlrpc" command requires a method name ( as in "currentTime.getCurrentTime"). You have to include any required parameters with the method (see the "call soap" example). The script takes the return value and makes an AppleScript date out of it. The code also adds three hours to the return value to bring it in line with the Eastern U.S. time zone.
tell application "http://time.xmlrpc.com/RPC2"
set returnValue to call xmlrpc ¬
{method name:"currentTime.getCurrentTime"}
set theDate to (returnValue as date) + (3 * hours)
end tell
The Web sites that provide Web services will usually explain what method names and parameters to use (see "http://www.xmlrpc.com/currentTime" for details on this script sample). Whether you like it or not, the Mac OS X system software takes care of the XML for you. The AppleScripter doesn't have to deal with parsing or translating the XML return value.
Call soap
The AppleScript command for using SOAP servers is predictably, "call soap." SOAP is a more complex protocol than XML-RPC, partly because SOAP allows you to exchange more complex datatypes. The AppleScript syntax is a little more lengthy for SOAP calls. Along with the "call soap" syntax, you have to provide values for the method name, “method namespace URI,” any method parameters, and the “SOAPAction.” Sites such as XMethods (where I found this SOAP server information) usually explain what default values to use for these various parameters. You couldn't possibly guess them!
This script gets a stock price (live, if the stock market is open) in a certain currency by providing the stock symbol and country name as parameters. In this case, we are using Sun Microsystems with the stock value in U.S. dollars. The odd looking "on getStockPrice(sym, _country)" part is an AppleScript handler that takes a stock symbol and a country name as parameters, then uses the “call soap” command to return the stock price. AppleScript handlers or subroutines are described in Chapter 8 ("Subroutines") of the AppleScript in a Nutshell book.
set sym to "SUNW"
set _country to "United States"
getStockPrice(sym, _country)
on getStockPrice(Symbol, theCountry)
try
with timeout of 30 seconds
tell application "http://soaptest.activestate.com:8080/PerlEx/soap.plex"
return (call soap ¬
{method name:"StockQuoteInCountry", ¬
method namespace uri:"http://activestate.com/",¬
parameters:{Symbol:Symbol as string, country:theCountry as string},¬
SOAPAction:"urn:activestate"} )
end tell
end timeout
on error errmesg
display dialog errmesg
end try
end getStockPrice
The "getStockPrice" handler includes an AppleScript "try" block, which can catch and optionally deal with any errors that occur in the script statements appearing within "try … end try." In terms of SOAP or XML-RPC calls, the response can be delayed by a network slowdown, and this can cause the script to "time out" in AppleScript parlance. Without using the "try" error-trapping statement, the script may crash gracelessly. The script also uses the "with timeout" statement to limit to 30 seconds the amount of time the script waits for a response to its SOAP request.
Web services are a very important development in the software world. It is very exciting that AppleScript has such clean integration with them.
Go for It
We have just only scratched the surface on the expansive possibilities for users and developers of AppleScript on Mac OS X. A likely subject for several future articles are the number of major applications that offer scripting support using AppleScript.
O'Reilly & Associates published (June 2001) AppleScript in a Nutshell.
Sample Chapter 7, Flow-Control Statements, is available free online.
You can also look at the Table of Contents, the Index, and the Full Description of the book.
For more information, or to order the book, click here.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 25 of 25.
-
Scripting finder commands
2005-08-06 09:19:48 Winn [Reply | View]
When I right click on a document in the finder, I would like the option to move it to a particular folder rather than "move to trash". How can I accomplish this. I'm an absolute novice.
Thanks.
-
AppleScript & SOAP (displaying search results)
2004-07-01 19:34:21 BHEIBERT [Reply | View]
I am trying to build a program in REALbasic using both RB and AppleScript. In RB I have a edit field (Search for...) and a popdown list (Select a engine...) I want to be able to go out on to the internet to search for whatever the user specified and display the results in the RB window. I was told on the REALbasic list that I need to use AppleScript and SOAP what kind of thing would I do in AppleScript and where can I find information on SOAP?
-
terminal script
2003-11-11 15:10:45 anonymous2 [Reply | View]
how would i enter numerous commands in succession with out it opening a new window? I want to make a telnet script that enters user name and password and then two more commands to get to a certain folder, any ideas? cwh9100@rit.edu -
terminal script
2004-02-16 09:02:30 jaharmi [Reply | View]
Generally speaking, I don't think there's a good way to use AppleScript scripts to run command line utilities that require user interaction.
You could do the interaction and then pass the results to a command line utility, if it accepts arguments.
For your example, you're really talking more about scripting Terminal (and I'm not sure of the state of that) rather than scripting the command line (with "do shell script" in AS).
-
databases/rondevous
2003-10-31 14:06:55 anonymous2 [Reply | View]
I have two ideas for Apple script apps, and I'm not sure how appropriate Apple script is for them:
the first I'd like to make a simple app that can do a database lookup, from a very large (sorted) file. If I have a text list with, say 7000 tab-delimited elements, can I use applescript to search that quickly? if it's a list of client phone numbers, I want to let people search by area code, then let them type in "513" and have it pull up all the cincinnati numbers. So it would display
cincinnati: 513-888-3333 Venogram Inc. Holly Witherton
the list is being exported in sorted format though, I'd also like to search by city or other fields.
I guess I need to know if I can make such a large document part of the package...so users don't have to download two parts, or have two files on their computer.
I'd also like information on using Applescript and Rondevous. Can Applescript find other computers with it? I'd like to write an app that grabs data one one machine, and displays it on the other I read the article on remote control...very close to what I want, but I'd like to be able to seek out the other machine if I don't know it's IP address!)
help, please!
Also, better discussion boards for this stuff anywhere?
-
Applescript and Internet Connect
2003-10-20 11:29:47 anonymous2 [Reply | View]
Is it possible to use Applescript to establish a VPN connection via the Internet Connect app? Internet Conenct apepars to be "scriptable" but I don't see how a VPN to a particular host can be setup using script commands.
-
[Q] How to get the current path from the Finder window?
2003-06-06 10:45:17 anonymous2 [Reply | View]
Hello. I'de like to have an AppleScript code that does what "DOS prompt here" PowerToy does.
To do it, the AppleScript should catch the open directory path from a Finder window that opens what you want to "cd" into.
And with the path, you should be able to open a terminal. Is it possible?
-
Alarm Clock with iTunes & Cron Solution
2003-01-01 21:19:47 anonymous2 [Reply | View]
I also tried to use cron to call an AppleScript via osascript to open a playlist in iTunes. The mac-as-alarm-clock seemed like a no brainer thing to do. But while the script worked from the command line, cron wouldn't execute it as expected.
Still not sure why, but osascript appears to have limitations requiring that it be called explicitly from the command line in order for it to work right...
The solution was to save the AppleScript in Script Editor as an Application, using the "Never Show Startup Screen" option. Then in the crontab file, just specify the full path to the executable AppleScript Application, avoiding using osascript altogether.
My AppleScript (saved to an Application called 'alarm2') looks like:
tell application "Finder"
set volume 2
end tell
tell application "iTunes"
activate
set the sound volume to 100
play playlist "wakeup"
end tell
my crontab entry looks like:
30 6 * * 1-5 root /Users/bbahner/alarm2
This works great and wakes me up to my favorite music rather than a bone-jarring alarm clock.
Hope this helps.
-
CLI, Applescript, and cron
2002-06-03 20:25:08 clf8 [Reply | View]
What you didn't touch on in the article is calling Applescripts from the terminal. /usr/bin/osascript, osacompile, and osalang.
I wrote a basic script that tells iTunes to play my WakeUp playlist in the morning, and saved it in the Library/Scripts in my home (~) directory. From the Terminal you can run "/usr/bin/osascript /Users/bob/Library/Scripts/iTunesWakeup.scpt", without the quotes. .scpt seems to be the recommended extension, and you can save it as plain text (edited in vi or your favorite editor), or in the Script Editor format.
From the command line, this works. But you've got to have some way to get it to run at the right time. One kludge (I use it as a sleep timer because of 'at' problems) is to write a script, I call it bed and put it in my ~/bin.
#!/bin/tcsh
sleep 1800;/Users/flowers/bin/iTunesStop &
Not much to it. When bed runs, it sleeps for 1800 seconds (30 minutes), then tells iTunes to stop. The & at the end puts the process in the background and returns the command prompt. The & will not work without the #!/bin/tcsh at the top. This is a complete hack, but it works.
But OS X is unix, and it has cron. Why can't I schedule a cron job to call my Applescript? Well, for some reason you can and you can't. This has worked on and off since 10.0 through 10.1.4. Actually, it usually worked right after an update for a couple of days/weeks. Then, and I don't know why, it stops working. Since cron can send you the output from your jobs, i've got a log of what gets returned when this happens:
zsh: read-only variable: PWD
syntax error: Can't get the application's event dictionary. (-2709)
I don't get that error when I call it myself, but the exact line called from cron gives this error. Can you all from O'Reilly help out with this one, or is the Terminal/Applescript integration just not there yet?
As for a replacement for the "bed" script, 'at' is a program that allows convenient scheduling of scripts. To use it, it has to first be enabled in the /etc/crontab. To do this, su to root and remove the "#" from the start of the /usr/libexec/atrun line. After that "kill -HUP pid" where pid is cron's process id, this will restart cron and reread the crontab. As always, if you're done being root, stop being root.
'at' allows command scheduling like 'at +2 min', then users enter commands/scripts, terminated with Ctrl-D. Every 10 minutes, atrun executes and checks for any jobs that are expired. No, at isn't the most precise of timers, but it works well for this purpose. And, if you want to increase the resolution, you can go back and edit the crontab.
But, for some reason cron cannot call Applescripts properly. Does anyone have this working, or an explanation of what might be going wrong?
-
Directing "do script with command" to existing Terminal window
2002-02-14 10:46:02 senior [Reply | View]
I'm building a 2 scripts to interface with the Terminal; the 1st to ssh to another host; the 2nd to execute commands to the open Teminal window. (I'm using 2 scripts because the first requires my login password which I'd rather do manually, and I'm not aware of any QuicKeys-like 'wait for user input' command).
1st thing I've hacked is:
--beg--
tell application "Terminal"
activate
tell window 1
do script with command "ssh me@host.com""
end tell
(* Closes that pesky extra window:*)
close window 2
end tell
--end--
Problem is the next script always sends the command to a newly-spawned window, no matter which windows I specify. How can I direct it to the window opened in the 1st script?
--beg--
tell application "Terminal"
tell window 1
do script with command "clear"
end tell
end tell
--end--
-
CLI & Applescript
2002-02-12 09:23:38 naepstn [Reply | View]
How extensively can you integrate CLI commands and Applescript?
Specifically, can I write an Applescript similar to your example you gave for printing, but after copying over a .ps file, would SSH to the Linux machine that the file was sent to (and which is acting as an LPR print server for the Windows print server), and then issue the following shell command over SSH:
lpr -P HP3200 myfile.ps
Ideally, if it could access the keychain to decrypt the SSH login password, that would be great, but it could also prompt me to enter the password each time, but it would have to display the keystrokes as asterisks or some other masking character.
Is this possible within the confines of Applescript, or would this require writing new methods or other such programming for which I lack the skills?
Cheers!
Noah
P.S. Is this going to be a recurring column? It would sure be nice if it was. :-) -
CLI & Applescript
2002-05-20 18:28:26 mpf [Reply | View]
I have written a document outlining how you can use ssh from within applescripts and store the passphrases in our keychain. You can find it at http://www.progsoc.org/~mpf/macosxsshlogin.html .
regards
matthew -
CLI & Applescript
2002-02-12 17:44:55 bwperry [Reply | View]
You can do a lot with AppleScript (AS) and "do shell script", which uses /bin/sh as the shell (as far as I know). Take the commands that you want to integrate into an AS and test them first with a "do shell script" command used in a simple script; experiment a bit. This is a new technology. I've found that certain types of shell commands passed to "do shell script" as arguments, such as the "history" command, will return errors.
As I suggested in my article, this has a lot of potential for combining advanced desktop automation with the wealth of Unix shell commands (particularly when given a user interface in Studio). I'd imagine that Apple would continue to refine and enhance what the scripter can accomplish with "do shell script."
I'd like this to become a recurring column. Email the O'Reily editors and make a request :)
-
perl and applescript answer
2002-02-09 10:52:16 bwperry [Reply | View]
You generally shouldn't use system commands that are launched by CGI programs and linked to Web forms, because someone could send a malicious shell command to the CGI program. That said, you can call AppleScripts from perl using the "osascript" shell command. If you type "man osascript" from a Terminal prompt, you can find out most of what you need to know about this command. Here's an example of a perl script that launches a bit of AppleScript:
#!/usr/bin/perl
use strict;
my $finder = "\"Finder\"";
my @arg = ("osascript -e 'tell app $finder to get file 1'");
system(@arg);
This script returns a reference to a file on your desktop, such as "document file osascript.txt". It uses perl's "system" built-in function. The "-e" switch to the osascript command indicates that the argument to osascript will not be a file name; it will be script source. Notice the way that the quotes around Finder (which AppleScript needs) are preserved by creating a perl variable first.
So I guess you could try running AppleScript from a perl CGI, but I haven't tested it yet. And it's potentially hazardous in terms of server security.
-
perl and applescript answer
2002-02-11 09:49:51 bradrice [Reply | View]
Perhaps you could use a future article to describe how to use Applescript as a CGI. I noticed your book is slim on this OS X server feature. What I am trying to do is cobble together a CGI that takes form data, builds a document with the data in a desktop app and then prints a PDF which is served back up to the browser.
-
PERL and Applescript
2002-02-08 06:24:29 bradrice [Reply | View]
I would like to know how a PERL CGI can launch and plug values from a web form into an AppleScript.
-
I miss MacroMaker
2002-02-07 12:07:55 reggoboy [Reply | View]
All I really want out of AppleScript right now was available years ago in a product called MacroMaker.
Remember that?
There was a little cassette icon in the menu bar. You choose "Record" and it starts recording what you do. You choose "Stop", assign a key combination, and ba-da-bing! you can reply that task whenever you want.
People keep talking about how A.S. automates your tasks. But it's more trouble to learn to write the code than it is to repeatedly do the task itself. MacroMaker was such a beautiful little tool. I wonder if they'll ever put this type of ease into A.S....
Dave
-
PHP and applescript
2002-02-05 07:35:56 DH_Ivory [Reply | View]
I'd really like to know if there was a way for a PHP script to activate an Applescript.
This would be cool. FOr instance you could upload an image and then get an Applescript to activate Photoshop to process it, resize, sepia, mask, etc... then copy it to the Library/WebServer/Documents/ directory where it could be dynamically included into a webpage - using PHP & mysql.
I do something similar using imagemagick now - but being able to use all the scriptable applications on a Mac would be awesome!!!
Are their any hooks possible - is this cover in "In a nutshell"? -
PHP and applescript
2004-02-16 08:59:23 jaharmi [Reply | View]
You can call a script from the command line with the osascript command. Check out its man page. You can either call a fairly uncomplicated line of AppleScript with its -e flag or you can call a full external script file (similar, in my mind, to what I've done with the little bit of awk I know).
In Panther, you can also do some image transformations at the command line or via AppleScript. Check out the sips utility (no man page, alas, do sips -h to get help) and the Image Events scriptable background application. They can't do everything ImageMagick or the like can do, but for some basic stuff (thumbnailing and so on), they may suit your needs (because they are accelerated for the G4/G5/GPU in Panther) or be part of a larger workflow (they can attach ICC color profiles).
-
Desktop picture?
2002-02-04 09:25:44 yezedi [Reply | View]
Is there a verified way to set a desktop background picture in the Finder under OS X? I tried script recording the actions of going into the Preferences and setting it, but that did not work.
The AquaBlue.jpg seriously irritates me, and my desktop pictures get reset after disconnecting my external monitor.
Educated answers only, please.
PS: I bought Applescript in a Nutshell, and to be honest was a little disappointed. While the book was well-written, I felt it didn't have a lot of OS X stuff in there. I'm sure this will be included in the next edition.
Now O'Reilly, how about an Applescript Cookbook (for OS X)? :-). I'm a UNIX dweeb who became an Apple dweeb because of OS X, and I'm suprised at how powerful Applescript appears to be, especially the hooks into apps. -
Desktop picture?
2004-02-16 08:55:21 jaharmi [Reply | View]
You can fairly easily set the Finder's desktop picture this just so:
tell application "Finder"
set the desktop picture to document file "Tiles Warm Grey.jpg" of folder "Desktop Pictures" of folder "Library" of the startup disk
end tell
I don't know of a way to script setting the background picture for a Finder window, yet, as of Panther. -
Desktop picture?
2002-02-10 12:40:34 mattchildress [Reply | View]
Try the free application ChangeDesktop, available (with source!) for free from http://www.classicalguitar.net/brian/software/
It's not applescript, it's a cocoa application, but it may either provide what you need straight away (dunno if it's applescriptable) or the source code may enlighten you.






This is a peculiarity I have to deal with using Firefox to access remotely my AOL e-mail account.
I know this should be easy to make, but I can't seem to.