Script Looking for Folder That's Not There

I have the following script (there’s many more items, but they’re all duplicates of this one, just looking at different folders).

tell application "Finder"
	set theFolderAlias to alias "Volumes:Mac Mini Local Backups:SmartBackup Local Backups:Local Documents:__changed:"
	delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
end tell

Basically, I’m creating a script to look at archives created by a backup program. But the issue I’ve run into is that during the early stages of using this backup program, if nothing has changed, the software doesn’t even create the “__changed” folder.

So, is there something I could add to the script to say "if the folder doesn’t yet exist, ignore it, rather than throwing an error?

You can wrap the command that you think may or may not fail, in a try block. Doing this will cause the script to silently error then continue on to the next command which is outside of the try block.

In your situation you could do something like this…

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:Mac Mini Local Backups:SmartBackup Local Backups:Local Documents:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	end try
end tell

Or you can add a command to perform if an error occurs within an an error clause, like this…

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:Mac Mini Local Backups:SmartBackup Local Backups:Local Documents:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		tell current application to (say "You Suck At This!")
	end try
end tell

-- Insert more commands to perform after the error occurs

You could also try something like using a conditional clause, like this…

tell application "Finder"
	if alias "Volumes:Mac Mini Local Backups:SmartBackup Local Backups:Local Documents:__changed:" exists then
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	else
		set theFolderAlias to (make new folder at desktop with properties {name:"__changed"}) as alias
	end if
end tell

display notification "Folder " & (theFolderAlias as text) & " was created"

AppleScript Error Handling

Thank you for the suggestions, I’ll do some reading tonight on the “try” command.

So, it’s door #1, door #2 or door #3. And, just to show you that I do in fact fully read responses, I think I’ll pass on door #2. Thanks for my laugh of the day!

FYI, the error command in door # 2 was not aimed at you. It was just the first thing that popped in my head and I figured you may get a laugh out of it.

Door #1 is what I went with, and it works perfectly. As for door #3, I had already tried manually adding whatever folder was missing, but it seems that the backup software is smarter than I am. It knows the difference between a folder that it creates, and one that the user manually created, and rejects the one the user created. Took me a while to figure that one out.

After doing a few runs and thinking about what I’m trying to accomplish I decided to go with door #2, minus the “You Suck At This.” What I ended up with is a script that will post a message window in the Finder letting me know which folders are missing. Ran the script with the portable SSD (where the backups are stored) not even plugged in and the error windows pop up one at a time (I have a total of fourteen folders the script looks for) waiting to be dismissed. So, if things are working, and all the folders are there, fine. If not, I’ll know exactly which backup is missing which folder.

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Documents Folder __changed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Documents Folder __removed is Missing"
	end try
end tell

Thank again.

1 Like

Homer712. I tested your script and it works great. If you have a lot of folders to process, you may want to consider using a list of the folders and a repeat loop.

set targetFolders to {"Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__changed:", "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__removed:"}
set text item delimiters to {":"}
tell application "Finder"
	repeat with anItem in targetFolders
		try
			set theFolderAlias to alias anItem
			delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
		on error
			display dialog "SmartBackup Local Documents Folder " & (text item -2 of anItem) & " is missing"
		end try
	end repeat
end tell
set text item delimiters to {""}

I’m keeping a copy of your script as a template. Not only does it work well, but it saves me the time and typing compared to mine when making changes, thanks!

Found an error. There’s a total of seven backup locations, and each has two folders that the script is looking for. If you add the next two folders to your script (Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local iCloud Folder:__changed:) and (Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local iCloud Folder:__removed:), on error of the second set of two folders, the error window still says “SmartBackup Local Documents Folder __changed is missing” and “SmartBackup Local Documents Folder __removed is missing” rather than referring to the iCloud Folder.

There’s no really great solution to that issue because the target paths differ. One solution is the following (note how the name of the folder is constructed with text items in the error statement and edit if desired):

set targetFolders to {"Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__changed:", "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__removed:", "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local iCloud Folder:__changed:", "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local iCloud Folder:__removed:"}

set text item delimiters to {":"}
tell application "Finder"
	repeat with anItem in targetFolders
		try
			set theFolderAlias to alias anItem
			delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
		on error
			display dialog (text item -4 of anItem) & space & (text item -3 of anItem) & space & (text item -2 of anItem) & " is missing"
		end try
	end repeat
end tell
set text item delimiters to {""}

Another solution employs a list of lists in which each sublist contains the path to the target folder and the folder name you want to use in the error dialog (edit the folder name as desired). This solution is a bit tedious but works well if the folder paths do not change often.

set targetFolders to {{"Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__changed:", "SmartBackup Local Documents Folder __changed"}, {"Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__removed:", "SmartBackup Local Documents Folder __removed"}, {"Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local iCloud Folder:__changed:", "Local iCould Folder _changed"}, {"Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local iCloud Folder:__removed:", "Local iCloud Folder _removed"}} -- each sublist contains a path and folder name for error dialog

tell application "Finder"
	repeat with aList in targetFolders
		try
			set theFolderAlias to alias (item 1 of aList)
			delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
		on error
			display dialog (item 2 of aList) & " is missing"
		end try
	end repeat
end tell

And, if you only have seven target folders, your original solution works well and benefits from simplicity. I would only use one tell application “Finder” statement, though.

Right now, simple is what I do best. But I’ll have to admit, that since that initial post, “Help Learning AppleScript” back on August 1st, I think I’ve learned a lot here at MacScripter. Grateful to all who have helped me along.

@Homer712 just a little friendly advice for you…

Finder is painfully slow in dealing with lists of files and folders. (and considerably worse as the lists get larger and larger) Try using System Events to deal with files and folders instead of Finder, whenever you can.

Continuing to use Finder like you are doing sometimes creates huge bottle-necks and sooner or later you will probably find your scripts error out because the Finder code timed out. Then you will have to start wrapping your Finder code within a with timeout of ... seconds clause because the default time out is only 120 seconds.

To demonstrate exactly what I’m talking about, I created a folder on my Desktop named “Test”. Then I created 5000 text files within that folder. This following AppleScript code will create that folder and files for you if you want to run some of your own testing.

set theFolder to (path to desktop as text) & "Test"

try
	alias theFolder -- checks if folder ~/Desktop/Test exists
on error errMsg number errNum -- If folder ~/Desktop/Test doesn't exist, creates ~/Desktop/Test folder and 5000 .txt files in it
	do shell script "mkdir ~/Desktop/Test ;cd ~/Desktop/Test ;touch File_{0001..5000}.txt"
end try

Then I used Finder then System Events to simply get the list of files with in that folder and I compared their timing results.

As you can see, Finder was generally 14 times slower.

Honestly though, for this kind of project, personally I would not use Finder or System Events. I would use the do shell script "find " command to retrieve the file list. (which is 25 times faster than using System Events)

If you use the code I posted above to create the “Test” folder with the 5000 text files in it, on your Desktop, here is all of the code I used to run the tests and you can check for yourself.

set theFolder to (path to desktop as text) & "Test"

tell application "Finder"
	set theFiles to (files of alias theFolder) as alias list
end tell

And…

set theFolder to (path to desktop as text) & "Test"

tell application "System Events"
	set theFiles to (path of items of alias theFolder)
end tell

And…

set theFiles to paragraphs of ¬
	(do shell script "cd ~/Desktop/Test ;find \"$PWD\" -type f -mindepth 1 -maxdepth 1 |sort -f")

So, I eliminated all but the first "tell application “Finder”, then I eliminated all the “end tell” statements but the last one, and it still works. Learned something new again, thanks.

Thanks for the suggestions. I’ll need to do some reading on modifying scripts from Finder to System Events. Right now the script (even looking at fourteen different folders) runs in the blink of an eye. But I will be using your scripts (and need to download Script Geek) and see what the differences in time are between my M1 MacBook Pro and my Intel 2014 Mac mini. You’ve given me a project for today, thanks.

Downloaded Script Geek and ran this script which has to look at fourteen folder locations:

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Documents Folder __changed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Documents Folder __removed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local iCloud Folder:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local iCloud Folder __changed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local iCloud Folder:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local iCloud Folder __removed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Installs:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Installs Folder __changed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Installs:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Installs Folder __removed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Movies:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Movies Folder __changed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Movies:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Movies Folder __removed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Music:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Music Folder __changed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Music:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Music Folder __removed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Photos Archive:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Photos Archive Folder __changed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Photos Archive:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Photos Archive Folder __removed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Pictures:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Pictures Folder __changed is Missing"
	end try
end tell

tell application "Finder"
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Pictures:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Pictures Folder __removed is Missing"
	end try
end tell

Here are the results for that script;

I then edited out all the extra (tell application “Finder” and “end tell”) from the script and here are the result for that script:

I’m assuming that the results are in seconds, so, while the exercise of converting the script from Finder to System Events will be a worthwhile learning experience, I think for now, my scripts (baby steps) relying on Finder are not in any danger of timing out.

Seem to have run into a very strange problem, could be script related, could be macOS related, but here goes. This is the script that I’m referring to (there are twelve more entries, but if there’s a fix I can apply it to the remaining entries:

try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__changed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Documents Folder __changed is Missing"
	end try
	
	try
		set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__removed:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "SmartBackup Local Documents Folder __removed is Missing"
	end try

Issue is this, it seems that the backup program “recreates” the folders the script is looking for, and if I now recreate the “path” to both the “__changed” and “__removed” folders in the script, the script will work perfectly. I do another backup, and the script fails once again.

Question is this, is there a way, within the script, to add some sort of “wild card” that will target the folders and not look at their created or modified dates. I’m not sure of what the issue is, but hopeful there is a solution.

What is the “back up program” that you keep mentioning? Is it a custom AppleScript application or some sort of actual backup software? It’s going to be difficult for people to diagnose your problem by supplying us with only snippets of your code and without knowing exactly what your “back up program” is actually doing.

Homer712. I’m also unsure what you’re asking, but the following code snippet appears to do what you want:

try
	set theFolderAlias to alias "Volumes:MacBook Pro Local Backups:SmartBackup Local Backups:Local Documents:__removed:"
	delete (get files of theFolderAlias whose creation date < ((current date) - 30 * days))
	delete (get folders of theFolderAlias)
on error
	display dialog "SmartBackup Local Documents Folder __removed is Missing"
end try

just in case: you can make your script much more concise and better manageable by doing something like this:

set pathsList to {your, paths, here}

repeat with aPath in pathsList
try
		set theFolderAlias to alias aPath
		delete (get items of theFolderAlias whose creation date < ((current date) - 30 * days))
	on error
		display dialog "appropriate message with folder name here"
	end try
end repeat

The backup software is called SmartBackup and is available (for free) here: SmartBackup - The free, fast, SSD optimised macOS cloning and folder sync utility.

But, please see my response to peavine below.