Error when deleting a file with applescript

I have created a simple script that takes a project folder on one drive, zips the folder, changes the name to the date and time it was zipped, and then adds it to a folder on a different drive for backup purposes. The last part checks to see if there are more than 10 zipped files in the backup folder and deletes the oldest one.

It is all working except the delete file part. I get the error:

tell application “Finder”
delete file “/Volumes/Client_Drive/Project_Backup/20150813_100409.zip”
→ error number -1728 from file “/Volumes/Client_Drive/Project_Backup/20150813_100409.zip”
Result:
error “Finder got an error: Can’t get file "/Volumes/Client_Drive/Project_Backup/20150813_100409.zip".” number -1728 from file “/Volumes/Client_Drive/Project_Backup/20150813_100409.zip”

I should add that I store the paths to the source drive and backup drive in two text files so I can change the paths there instead of storing them in the script. The first two “set theFile” commands load the paths into the script

the paths stored in text files are like this:

/Volumes/Client_Drive/Project_Backup

/Users/dksounds/Desktop/Project_Folder

My code is below, can anyone help. I think it’s just a file naming issue i’m missing.

set theFile to POSIX file "/Users/dksounds/Desktop/BackupButton/Prefs/Button_3_Source.txt"
open for access theFile
set SourcefileContents to (read theFile)
close access theFile

set theFile to POSIX file "/Users/dksounds/Desktop/BackupButton/Prefs/Button_3_Backup.txt"
open for access theFile
set BackupfileContents to (read theFile)
close access theFile



set {year:y, month:m, day:d, time string:t} to (current date)
set date_format to (y * 10000 + m * 100 + d) as string
set time_format to (t) as string
set t to (do shell script "echo " & "'" & t & "'" & " | sed  's/://g' ")
set N to count of characters of t
set t to characters 1 thru (N - 3) of t
set t to t as text
set thedate to date_format & "_" & t as text

set ToBeZippedFolder to POSIX path of (SourcefileContents as text)
set zipfolder to (POSIX path of (BackupfileContents as text) & "/" & thedate & ".zip")


do shell script "zip -r " & zipfolder & " " & ToBeZippedFolder & ""


set fList to (list folder (POSIX path of (BackupfileContents as text)) without invisibles)
if (count fList) > 10 then
	repeat with a from 1 to ((count fList) - 10)
		set dList to ((POSIX path of (BackupfileContents as text)) & "/" & {item a of fList})
		tell application "Finder"
			delete file dList
		end tell
	end repeat
end if

Model: mac book pro
AppleScript: 2.4
Browser: Safari 600.1.25
Operating System: Mac OS X (10.10)

You ask the Finder to delete a file defined by a POSIX path which it can’t treat. It knows only HFS+ pathnames.

System Events is able to delete files defined by POSIX path but it doesn’t move the files to the trash, it really delete them.

If you need to move the file to the trash, you must replace

set dList to ((POSIX path of (BackupfileContents as text)) & “/” & item a of fList)
tell application “Finder”
delete file dList
end tell

by

set dList to ((POSIX path of (BackupfileContents as text)) & “/” & {item a of fList})
set dList to POSIX file dList as alias
tell application “Finder”
delete file dList
end tell

or by

set dList to (BackupfileContents as text) & “:” & item a of fList
tell application “Finder”
delete file dList
end tell

Yvan KOENIG running Yosemite 10.10.4 in French (VALLAURIS, France) jeudi 13 août 2015 21:48:00

. System Events can do that, too

set dList to ((POSIX path of (BackupfileContents as text)) & "/" & item a of fList)
tell application "System Events"
	move file dList to trash
end tell

almost all path to . folder relative paths are accessible in System Events, just without path to

Thanks Stefan

I missed this one.

Yvan KOENIG running Yosemite 10.10.4 in French (VALLAURIS, France) jeudi 13 août 2015 23:04:41

Thanks to you both for your fast response!

I used this code and it worked great!!

set fList to (list folder (POSIX path of (BackupfileContents as text)) without invisibles)
if (count fList) > 10 then
	repeat with a from 1 to ((count fList) - 10)
		set dList to ((POSIX path of (BackupfileContents as text)) & "/" & item a of fList)
		tell application "System Events"
			move file dList to trash
		end tell
	end repeat
end if

You both mentioned using System Events to delete the file without moving it to trash. How would I alter the lines above to just delete it without putting it in trash?

Thanks

David

Just use “delete file dList”.

A couple of other suggestions. You use:

set fList to (list folder (POSIX path of (BackupfileContents as text)) without invisibles)
<snip>
 set dList to ((POSIX path of (BackupfileContents as text)) & "/" & item a of fList)

You need to be careful mixing POSIX and HFS paths. Suppose you have a file containing a slash in its name, which is legal under HFS and will be passed to list file – your script is going to error. You should stick to one or the other, or convert whole paths – not in pieces.

Also, you use this for the date string:

set {year:y, month:m, day:d, time string:t} to (current date)
set date_format to (y * 10000 + m * 100 + d) as string
set time_format to (t) as string
set t to (do shell script "echo " & "'" & t & "'" & " | sed 's/://g' ")
set N to count of characters of t
set t to characters 1 thru (N - 3) of t
set t to t as text
set thedate to date_format & "_" & t as text

That’s a bit long-winded (and slow, not that it matters much here), and it relies heavily on the state of text item delimiters, making it potentially fragile.

FWIW, here’s an alternative:

use framework "Foundation"

set theFormatter to current application's NSDateFormatter's new()
theFormatter's setDateFormat:"yyyyMMdd_HHmm"
set theDate to (theFormatter's stringFromDate:(current application's NSDate's |date|())) as text

Shane,

Your idea’s are very helpful. I have a question though. The date routine you purposed is much better than what I had, but I get an error when running it in my solution.

When I run your code stand alone, it works. When I place your code in instead of by block, I get an error on the " do Shell script command" when I try to compile.

How to I get your code in place of mine?

Thanks

David

You may try to use this edited version.

use framework "Foundation" # REQUIRED
use scripting additions # REQUIRED to compile the Standard Additions commands

set p2d to path to desktop as text

set theFile to p2d & "BackupButton:Prefs/Button_3_Source.txt"
open for access theFile
set SourcefileContents to (read theFile)
close access theFile

set theFile to p2d & "BackupButton:Prefs:Button_3_Backup.txt"
open for access theFile
set BackupfileContents to (read theFile)
close access theFile


set theFormatter to current application's NSDateFormatter's new()
theFormatter's setDateFormat:"yyyyMMdd_HHmm"
set theDate to (theFormatter's stringFromDate:(current application's NSDate's |date|())) as text

set ToBeZippedFolder to POSIX path of (SourcefileContents as text)
set zipfolder to POSIX path of ((BackupfileContents as text) & ":" & theDate & ".zip")


do shell script "zip -r " & zipfolder & " " & ToBeZippedFolder & ""


set fList to list folder (BackupfileContents as text) without invisibles
if (count fList) > 10 then
	repeat with a from 1 to ((count fList) - 10)
		set dList to (BackupfileContents as text) & ":" & item a of fList
		tell application "System Events"
			delete file dList
		end tell
	end repeat
end if

I’m sure that it compiles.

Yvan KOENIG running Yosemite 10.10.5 in French (VALLAURIS, France) vendredi 14 août 2015 21:49:40

Yvan THANKS!!!

The problem was I didn’t have the use statements at the top.

Thanks for the other fixes to my very sloppy code. I’m still a learnin.

I will try them out today!!!

Yvan,

I tried your code but had two problems.

First with my code: I get a file name of: 20150814_152552.zip (No slash at front)

set ToBeZippedFolder to POSIX path of (SourcefileContents as text)
set zipfolder to (POSIX path of (BackupfileContents as text) & theDate & ".zip")
do shell script "zip -r " & zipfolder & " " & ToBeZippedFolder & ""

With your code: I get a file name of: /20150814_152552.zip (extra Slash at front)

set ToBeZippedFolder to POSIX path of (SourcefileContents as text)
set zipfolder to POSIX path of ((BackupfileContents as text) & ":" & theDate & ".zip")
do shell script "zip -r " & zipfolder & " " & ToBeZippedFolder & ""

Is there a way to use yours but remove the extra / in name?

The other issue is in the last block of code that looks for 10 files and deletes the oldest one. My code works as expected, but using your code, I receive this error after there are 10 files and you try to run 11th time.

Result:
error “System Events got an error: Can’t get file "/Volumes/Client_Drive/Project_Backup/:/20150814_152552.zip".” number -1728 from file “/Volumes/Client_Drive/Project_Backup/:/20150814_152552.zip”

Thanks for you help:

This is a repost of my entire code before your two blocks were added. This works as expected, no extra / in name and deletes oldest file when more than 10 exist, but it has my sloppy coding with file paths:

use framework "Foundation" # REQUIRED
use scripting additions # REQUIRED to compile the Standard Additions commands


--Read Path for Source
set theFile to POSIX file "/Applications/BackupButton/Prefs/Button_3_Source.txt"
open for access theFile
set SourcefileContents to (read theFile)
close access theFile


--Read Path for Backup
set theFile to POSIX file "/Applications/BackupButton/Prefs/Button_3_Backup.txt"
open for access theFile
set BackupfileContents to (read theFile)
close access theFile


--Set the Time Stamp
set theFormatter to current application's NSDateFormatter's new()
theFormatter's setDateFormat:"yyyyMMdd_HHmmss"
set theDate to (theFormatter's stringFromDate:(current application's NSDate's |date|())) as text


--Set path for folder to be zipped and zip it
set ToBeZippedFolder to POSIX path of (SourcefileContents as text)
set zipfolder to (POSIX path of (BackupfileContents as text) & theDate & ".zip")
do shell script "zip -r " & zipfolder & " " & ToBeZippedFolder & ""


--Check for count of files over 10, delete oldest zip files
set fList to (list folder (POSIX path of (BackupfileContents as text)) without invisibles)
if (count fList) > 10 then
	repeat with a from 1 to ((count fList) - 10)
		set dList to ((POSIX path of (BackupfileContents as text)) & "/" & item a of fList)
		tell application "System Events"
			--move file dList to trash
			delete file dList
		end tell
	end repeat
end if

We are having to guess what’s in your file, but by the look of it, BackupfileContents already includes a trailing colon. If that’s the case, deleting & “:” in the two cases where it’s used will fix the problems.

Shane,

the text file “Button_3_Backup.txt” has this line of text in it. /Volumes/Client_Drive/Project_Backup/

the text file “Button_3_Source.txt” has this line of text in it. /Users/dksounds/Desktop/Project_Folder/

They are just simple txt files that store the path to source and backup drives that my applescript app reads when it runs. That way I can change the path in the text and use the same app.

thanks for your help

David

As you already have POSIX paths, there’s no need to keep using POSIX path in your code. You should, however, use quoted form in the do shell script line, otherwise you risk problems if your paths contain quotes or spaces.

You deletion code is relying on the names being returned sorted in alphabetical order. That’s the case with HFS+ volumes, but it’s not guaranteed elsewhere. However, if you’re happy with that, you can simplify things further:

use framework "Foundation" # REQUIRED
use scripting additions # REQUIRED to compile the Standard Additions commands

set p2d to path to desktop as text

set theFile to p2d & "BackupButton:Prefs/Button_3_Source.txt"
open for access theFile
set SourcefileContents to (read theFile)
close access theFile

set theFile to p2d & "BackupButton:Prefs:Button_3_Backup.txt"
open for access theFile
set BackupfileContents to (read theFile)
close access theFile


set theFormatter to current application's NSDateFormatter's new()
theFormatter's setDateFormat:"yyyyMMdd_HHmm"
set theDate to (theFormatter's stringFromDate:(current application's NSDate's |date|())) as text

set ToBeZippedFolder to quoted form of SourcefileContents
set zipfolder to quoted form of (BackupfileContents & theDate & ".zip")


do shell script "zip -r " & zipfolder & " " & ToBeZippedFolder & ""

tell application "System Events"
	if (count of files of folder BackupfileContents) > 10 then
		delete files 1 thru 10 of folder BackupfileContents
	end if
end tell

If you’re nervous about the assumption of alphabetical order (and these are backups after all), you can use the Finder to sort the files by name or do it using AppleScriptObjC. There’s a thread here now on the issue of sorting files.

Anyway, here’s an alternative to the System Events block above:

-- make URL of folder
set anNSURL to current application's |NSURL|'s fileURLWithPath:BackupfileContents
-- get file manager
set theNSFileManager to my NSFileManager's defaultManager()
-- get list of visible URLs
set theItems to (theNSFileManager's contentsOfDirectoryAtURL:anNSURL includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value))
if theItems's |count|() > 10 then
	-- sort items by name
	set theSortDesc to current application's NSSortDescriptor's sortDescriptorWithKey:"lastPathComponent" ascending:true
	set theItems to the theItems's sortedArrayUsingDescriptors:{theSortDesc}
	-- delete them
	repeat with i from 1 to 10
		(theNSFileManager's removeItemAtURL:(theItems's objectAtIndex:(i - 1)) |error|:(missing value))
	end repeat
end if

Shane,

Thanks so much!!! I was just researching how to do the paths with “use quoted form” when I saw this. I knew it was the way to go so I can have spaces in the names.

The code looks great and I’ll try it later tonight and tell you what happens.

David

I was wrong when I edited :

set zipfolder to (POSIX path of (BackupfileContents as text) & theDate & “.zip”)
as
set zipfolder to POSIX path of ((BackupfileContents as text) & “:” & theDate & “.zip”)

For the other instruction, as you wrote :
set dList to ((POSIX path of ( BackupfileContents as text)) & “/” & item a of fList)
it was “logical” to assume that BackupfileContents was an Hfs+ path because there is no need to coerce a Posix path to a Posix path and, as you added a slash it was “logical” to assume that the level delimiter was not available at the end of this path.

I forget (quite always) that in a Posix path, two consecutive slashes are treated as a single one.
/a/posix/path behave the same than /a//posix//path
In Hfs+ path, we aren’t allowed to have two consecutive colons.

Look at

set anExistingFile to "christopher.pl"

set hPath to (path to desktop as text)
set pPath to POSIX path of hPath

set maybe1 to pPath & "/" & anExistingFile
log maybe1
set maybe2 to hPath & ":" & anExistingFile
log maybe2
tell application "System Events"
	path of disk item maybe1
	log result
	path of disk item maybe2
	log result
end tell

It will issue an error on the instruction path of disk item maybe2 because there are two colons before “christopher.pl”

Yvan KOENIG running Yosemite 10.10.5 in French (VALLAURIS, France) samedi 15 août 2015 10:14:50