Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

do script ... please wait

i need to process a command through the terminal. for whatever reason i need to process this particular command using the do script command.

the do shell script command will not parse the command properly.

the only problem is that i need to wait until the shell command is finished before the rest of the script continues.

Any suggestions?

Thanks,
-P

Mac MINI, Mac OS X (10.5.6)

Posted on Aug 7, 2009 7:44 AM

Reply
8 replies

Aug 8, 2009 3:11 PM in response to Noaks

Good catch, Noaks. I'd not noticed that before.

Upon digging, though, I've come up with an even better revision. It turns out (at least in Leopard, maybe earlier versions, too) that do script actually returns a reference to the window (or tab) where the command is executing.

It doesn't obviate the need to delay before checking the window status, but it does eliminate any confusion over window ordering, etc.:

tell application "Terminal"
set myWindow to do script "sleep 10"
delay 1
repeat while (busy of myWindow)
delay 1
end repeat
end tell

Aug 7, 2009 10:26 AM in response to Pendal

the do shell script command will not parse the command properly.


Without seeing the command you're trying, it's impossible to tell why, but it's almost certainly an issue of escaping - certain characters (such as quotes, backslashes, etc.) need to be escaped in AppleScript so they're passed to the shell in the form it expects. Posting the command should make it easy to fix.

the only problem is that i need to wait until the shell command is finished before the rest of the script continues.


If you used do shell script and not Terminal.app, this would be the default. If you require Terminal.app for some reason then you have several options.

One is to poll the terminal window, looking at the last line of the window content to see if it's a prompt (indicating the process has finished).
Another approach is to capture the PID of the process and use that in another do shell script command that polls for that process. This might be tricky if you expect the process to continue processing in the terminal window since capturing the PID can be hit-or-miss.

Aug 7, 2009 8:11 PM in response to Pendal

The approach I've used successfully is to add the following immediately after the do script command in AppleScript:

repeat
tell application "Terminal" to set BI_ to busy of front window
if BI_ is false then exit repeat
end repeat
end tell


This stalls the AppleScript until the Terminal command is complete. There may be some downside to doing this, but none has surfaced so far.

Aug 7, 2009 11:27 PM in response to Noaks

Interesting approach, Noaks, and it should work.

I'd just make one change, though. You're always comparing the front window, which means that if the user changes focus (e.g. opens another Terminal window, or switches to another one), the script will check that window instead.

A solution to that one would be to capture the front window immediately after the do script and use that reference in the repeat loop:

tell application "Terminal"
do script "blah"
set frontWindow to window 1
repeat until busy of frontWindow is false
sleep 1
end repeat
end tell

Aug 8, 2009 3:15 AM in response to Camelot

Ah, sleep! Where does that come from, I need it!?

Seriously, is "sleep" a valid term?

But your concern is definitely a valid one, something I've thought about in other instances where I've referenced the front window. In some cases, I've referenced a window id. It's an oversight, but I didn't do so in this case.

Except for "sleep," I think the following is equivalent to your approach (correct me if I'm wrong):

tell application "Terminal"
do script "blah"
set W_ to windows of application "Terminal" -- must go immediately after "do script" command; I suppose there's a tiny chance someone might slip in a different front window before this line gets executed, so maybe it's not entirely foolproof. But it seems to me that could also occur with your version.
repeat until busy of (item 1 of W_) is false
delay 0.1
end repeat
end tell


Message was edited by: Noaks

Aug 8, 2009 12:46 PM in response to Pendal

CORRECTION! CORRECTION! CORRECTION!

Upon further tests of this approach, I found that it was not reliably stalling the AppleScript -- and I determined why as well. This applies to all approaches discussed, whether Camelot's or mine.

The problem was that, after the "do script" is called, 'set frontWindow to window 1' (Camelot) or 'set W_ to windows of application "Terminal"' (me) may not identify the proper window as window 1 -- time is needed for that window to establish itself. On my computer, with my test script, the threshold is ~0.3 second; using 1 second would be sensible to gain a safety margin. I don't know whether a slow computer might increase the delay needed beyond this.

Given that, the simple solution is to add a 1-second delay at the appropriate point in the script.

For Camelot's approach, the script would become:

tell application "Terminal"
do script "blah"
delay 1
set frontWindow to window 1
repeat until busy of frontWindow is false
--sleep 1 (sorry, I find the script won't compile with this!)
end repeat
end tell


For my approach, the script would become:

tell application "Terminal"
do script "blah"
delay 1
set W_ to windows of application "Terminal"
repeat until busy of (item 1 of W_) is false
end repeat
end tell


I suppose this slightly increases the chance that someone will slip in a different "window 1." The only solution I can see for that would be to reference the window by its name; but that, too, might be compromised if a different "window 1" has the same name.

How do you test whether the delay introduced is sufficient? Do this: in a new Script Editor window enter

tell application "Terminal"
do script "blah" -- use a command that will take at least a few seconds to execute
delay 1
set W_ to windows of application "Terminal"
repeat until busy of (item 1 of W_) is false
end repeat
end tell
beep 5


If, upon executing the AppleScript, you get 5 beeps immediately, then the delay is inadequate. The 5 beeps should not occur until Terminal finishes its chore.

do script ... please wait

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.