help with script not quitting

Hi all
looking for some help with a script. (I’m new at scripting)
This is an automated backup script using rsync. I’ve pasted only the last (and relevant) portion of the script below. I added the opening 'tell application “finder” tag so that it looks normal. There’s a couple more blocks above what I posted, (within the tell finder tag) but they work fine, so I didn’t include them. There’s also a couple set statements that set the path and disk of the variables ‘a’ and ‘b’. They’re outside of the opening ‘tell finder’ tag, at the very top of the script.

The problem I’m stumped on is that when the script reaches the end of the checking destination part, if the destination is not there, it’s supposed to write to the log, display the dialog (it works fine to this point) and then quit once the dialog is answered. (tell me - quit - end tell within the if statement.) Instead of quitting, it goes on to run the next portion of the script - the part that runs rsync. It does this once I click one of the dialog buttons. I’ve tried changing around the blocks of the script, and even though the code is the same as the other blocks, it only happens on the last section before the rsync portion. According to the logs, (and from what I can see on screen) when you click to dismiss the dialog on the ‘check for destination’ part, it skips over the following 'tell me - quit - end tell" block (it shouldn’t) and skips the ‘else’ block (like it should) and goes on to the ‘try’ block, runs rsync, gets an error (from rsync - destination not found), writes the error to the log, displays the error dialog from the rsync section, and then quits immediately without waiting for the user to click a button.

If I enclose the rsync portion of the code within the end tell (finder) tag, it works as expected, but it hangs up the finder until the backup is complete.

first, what’s going on, 'cause I can’t see what’s wrong! I’m sure I’m overlooking something, but I just can’t see it.
I wouldn’t mind rsync running within the ‘tell finder’ tags, if it didn’t hog up finder. If the only fix is enclosing rsync in the finder tags, Is there a way to forcce it to run in the background so it doesn’t make finder appear to be hung?

Thanks in advance for any help - it’s appreciated. I’ve gotten this far on my own, but I don’t even know what to do about this one.
Here’s the code. I can paste the entire script if needed.

	
tell application "Finder"
	--check for destination path
	
	
	if (folder b of disk a exists) = false then
		do shell script "logger -s Backup: Destination path not found: Backup canceled."
		
		activate
		display dialog "There was a problem backing up your files. Please see the log for details." with icon 2 buttons {"Show Log", "OK"} default button 2
		if button returned of result is "show log" then
			tell application "Console"
				open "/var/log/system.log"
				activate
			end tell
		end if
		tell me
			quit
		end tell
		
	else
		
		do shell script "logger -s Backup: Destination path OK. Performing backup."
	end if
	
	
end tell


--perform backup

try
	do shell script "rsync -ac --delete /foo/bar /Volumes/jezebel/Archive/Backup"
on error errMsg
	
	do shell script "logger -is Backup: Error reported by rsync:" & quoted form of errMsg & ": Backup canceled."
	
	activate
	display dialog "There was a problem backing up your files. Please see the log for details." with icon 2 buttons {"Show Log", "OK"} default button 2
	if button returned of result is "show log" then
		tell application "Console"
			open "/var/log/system.log"
			activate
		end tell
	end if
	tell me
		quit
	end tell
	
end try

do shell script "logger -s Backup: Completed sucessfully."

tell application "Finder"
	
	activate
	display alert "Your files have been backed up."
	
	
end tell


hi iwn,

what if you put the ‘backup’ portion in a handler and called it from within your else block, like this:


tell application "Finder"
	--check for destination path
	
	
	if (folder b of disk a exists) = false then
		do shell script "logger -s Backup: Destination path not found: Backup canceled."
		
		activate
		display dialog "There was a problem backing up your files. Please see the log for details." with icon 2 buttons {"Show Log", "OK"} default button 2
		if button returned of result is "show log" then
			tell application "Console"
				open "/var/log/system.log"
				activate
			end tell
		end if
		tell me
			quit
		end tell
		
	else
		
		do shell script "logger -s Backup: Destination path OK. Performing backup."
		doBackup()
	end if
	
	
end tell


--perform backup
on doBackup()
	try
		do shell script "rsync -ac --delete /foo/bar /Volumes/jezebel/Archive/Backup"
	on error errMsg
		
		do shell script "logger -is Backup: Error reported by rsync:" & quoted form of errMsg & ": Backup canceled."
		
		activate
		display dialog "There was a problem backing up your files. Please see the log for details." with icon 2 buttons {"Show Log", "OK"} default button 2
		if button returned of result is "show log" then
			tell application "Console"
				open "/var/log/system.log"
				activate
			end tell
		end if
		tell me
			quit
		end tell
		
	end try
	
	do shell script "logger -s Backup: Completed sucessfully."
	
	tell application "Finder"
		
		activate
		display alert "Your files have been backed up."
		
		
	end tell
end doBackup

does that work? seems like a good way to do it.

cheers.

Thanks Waltr
I had a glimmer of hope, but I just tried it and got the same results.
fyi, you posted your reply while I was editing my post to clarify more what was going on, if that helps.

I’m not nuts, am I? It should be quitting as expected, right?
aaagh

wait - I spoke to soon - I put the handler in the wrong place. it works as you suggested, but now to see if it hogs the finder.

holy crap, it worked! the script is behaving exactly as I expected it to. why?
I had to add “my” to the handler:

			
	else
		
		do shell script "logger -s Backup: Destination path OK. Performing backup."
		my doBackup()
	end if
l

You needed the “my” because you were in a “tell application “Finder”” block and the Finder doesn’t have a “doBackup” instruction - your script does. You’re really saying “doBackup that’s in the script, not the Finder”

hi iwn,

ah–>i think that’s because you call the handler from within a ‘tell application’ block. i forgot about that! glad you worked it out…

cheers.

ETA: application to ‘tell’. also, Adam beat me to it. thanks Adam!

Thanks a bunch for the help, everyone!

Can someone explain to my why it treats code differently when it’s in a subroutine? Isn’t it like an include file for HTML, where it, in essence, inserts the code in place of the “my doBackup()” handler? I plan on taking all that verbose error scripting and putting it into a subroutine (because it’s repeated about 4 times in the script) but with my luck, it’ll break the script and I won’t know why.

Everything is working perfectly. If you (or anyone else) is interested, I have a couple more bugs that have been stumping me.
In this part of the code:

set x to physical size of (folder c of startup disk) as number
	set x to (x / 1024 / 1024 / 1024)
	set n to (free space of disk a) as number
	set n to (n / 1024 / 1024 / 1024)

I’ve been saving this bug for later. I think this is going to be a big one - “set x to physical size” returns an error when it’s reading an encrypted home folder (Some bug in 10.4 I hear?) or if I’m trying to use any form of Finder’s home folder path ( ~ ) or (path to home folder). fyi, it needs to be flexible enough to be able to read an encrypted home folder as well as an unencrypted one. That’s why I was hoping ‘path to home folder’ would work, but it doesn’t.
I would like to simply specify “path to home folder” everywhere or even better yet, in the ‘c’ variable, because that’s never going to change. the other variables will, depending on who uses the script, and it would be nice to only have to change it in one place.
Every time I try anything like this, the script can’t get the size of the folder. If it’s encrypted, I have to specify the absolte path to the .sparseimage file to get the size.

I need to pass the ‘a’ ‘b’ ‘c’ variables (paths) to rsync using POSIX. This tripped me up before and I gave up on it until I got the rest of the bugs worked out. Jezebel is a disk name that’s called via the variable in the beginning of the script so the script will exit gracefully if the disk is not plugged into my powerbook:

set a to "jezebel"
set b to "archive:backup"
set c to "foo:bar"

Better yet, I’d like to use ‘POSIX path of’ so I can enter the paths (in the variable) in “real” syntax ie: archive/backup but that seemed to trip up the script. I had so many other bugs going on when I was trying it, that maybe I’ll have better luck now that it’s all working fine.

Any insight?

hi iwn,

after your if/else block the rest of your code was executed no matter what! like this:

[code] if this then
this
else
that
end

bunch of other stuff gets executed regarless of if/else block[/code]
by putting it into a handler or subroutine, we keep all the code tidily inside your if/else block. alternatively you could have just put all of the code into the if/else block, but i prefer to use handlers since it makes things more modular and easy to look at.

cheers.

ETA: psuedocode.

I get it…
I see the light - it makes sense now!
but that doesn’t explain why the script ignored the tell me - quit - tell me block - it should have completed the ‘then’ statement before moving on to the ‘else’ statement. That would have made it quit without completing the remainder of the script (the rsync part). That was the idea, anyway…
I give up on figuring out why, but It works.
I think once this is finished, I’ll stick to HTML/CSS. At least I don’t have to tell a web browser what to do with a mouseclick! :slight_smile:

thanks!

Hi iwasnevy,

That’s the normal mode of operation of the quit command. Note that ‘quit’ is an application command. Using quit quits the application after running all statements. That’s why it’s ususally used in stay open apps, because non-stay open apps quits anyway, when all statements are run.

For non-stay open apps, use ‘return’ instead of ‘quit’. You can also use a user canceled error:

error number -128

These will make the script quit imediately. The error -128 is used for quitting from subroutines, because a return in a subroutine just executes a return from the subroutine.

I almost forgot, in stay open apps, if you want to quit without it completing the rest of the statements, use if then statements like:

if something then
quit
else
– rest of statements
end if

This is used a lot in idle handlers.

gl,

Here’s a simple example showing how quit works:


global f
on run
	set f to true
end run
on idle
	if f then
		quit
	end if
	beep 3
	return 1
end idle

You save this as stay open application. You would think that it wouldn’t beep 3 times, but you’re wrong! It should be written like this:


global f
on run
	set f to true
end run
on idle
	if f then
		quit
	else
		beep 3
	end if
	return 1
end idle

Now it doesn’t beep. However, you don’t notice it, but the return is executed. It comes back in one second and quits.

gl,