Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

An AppleScript to create a size-limited trash can System
As a recent Mac convert, I want a trash can I don't have to remember to empty. I searched high and low for a utility to mimick Windows' Recycle Bin, where a maximum limit can be set on the size of the bin, and the least recently trashed files are deleted to keep the bin under the limit.

I found Compost, but it costs money :). So I wrote my very first AppleScript instead, which suits me fine. With this script added as a Folder Action on the user's ~/.Trash folder, trashed items' modification dates are updated to the time of trashination. Then the script checks if the total size of the Trash folder is under a certain limit, and if it's not, it starts deleting items until the trash is under the limit.

This only works for the Trash folder in your home folder -- if you have links to trash on remote volumes, frankly, I have no idea what's going to happen. The size of the trash folder is calculated dividing the number of file blocks reported by du by 2048, because that's what worked on my MacBook. Your Mac might be different. Finally, if you trash a file bigger than your trash limit, all of your trash will be emptied.

To set this up, save the code as a script in the folder /Users -> your_username -> Library -> Scripts -> Folder Action Scripts, then open the app Folder Actions Setup (in the Applications -> AppleScript folder), and manually add the folder ~/.Trash as an action folder, and then add this script to it. Then try trashing! The limit is set in the code to 2048 megabytes. If anyone's written a better script, or knows a better way, please let me know.
    •    
  • Currently 2.71 / 5
  You rated: 5 / 5 (7 votes cast)
 
[17,161 views]  

An AppleScript to create a size-limited trash can | 21 comments | Create New Account
Click here to return to the 'An AppleScript to create a size-limited trash can' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
An AppleScript to create a size-limited trash can
Authored by: wallybear on Nov 07, '06 08:19:36AM

Two suggestions:

1) Size of clusters is not necessarily 2048 bytes, so it's better to add the -k parameter, that gives you the block count using 1Kb blocks (i.e. the size in kilobytes):

change the command
du -s ~/.Trash/ | awk '{print $1}'
with
du -sk ~/.Trash/ | awk '{print $1}'

and then remember to divide by 1024 instead of 2048.

2) your script doesn't handle correctly filenames containing quotes. You can fix this replacing every occurence of

quote & (POSIX path of oldest_file) & quote

with

quoted form of (POSIX path of oldest_file)

that will handle for you all cases.



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: dipsomaniac on Nov 07, '06 10:12:47AM
Trash Timer is my solution. One of the things I like about a desktop over a laptop is having a large enough hard drive so you don't have to worry about emptying the trash often. I also only throw away things I'm absolutely sure I don't need. Anything I think there is the slightest possibility I might use again goes into a separate folder until I know I don't need it.

[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: dipsomaniac on Nov 07, '06 10:14:41AM

And that was supposed to be a separate entry, not a reply to the first post per se.



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: carmst on Nov 07, '06 10:56:35AM
Thanks, the -k option was exactly what I gave up looking for, and I had no idea mac filenames permitted quotes.

I've updated the script for those changes, and there's now a check to see if any of the incoming items exceeds the limit, so one item doesn't wipe your trashcan.


on adding folder items to this_folder after receiving added_items
	try
		-- Size limit of the Trash folder in MB
		set trash_limit to 2048
		
		--  Check size & Touch all incoming items to update the modified date to now
		repeat with i from 1 to the count of added_items
			set a_file to item i of added_items
			
			-- Get incoming item size and check if it exceeds the max trash size
			set a_file_size to ((do shell script "du -sk " & quoted form of (POSIX path of a_file) & "| awk '{print $1}' ") / 1024)
			if a_file_size is greater than trash_limit then
				display dialog quote & (name of (info for a_file)) & quote & " is too big for the Trash. Would you like to delete it permanently?" buttons {"Yes", "No"} default button "No"
				set response to the button returned of the result
				if the response is "Yes" then
					-- Permanently delete
					set sh_script to "rm -Rf " & quoted form of (POSIX path of a_file)
					do shell script sh_script
				end if
				if the response is "No" then
					-- Rename and move to Desktop
					set sh_script to "cd ~/Desktop;mv " & quoted form of (POSIX path of a_file) & " " & quoted form of (POSIX path of a_file)
					do shell script sh_script
					display dialog quote & (name of (info for a_file)) & quote & " has been moved to the Desktop."
				end if
			end if
			if a_file_size is not greater than trash_limit then
				set sh_script to "touch " & quoted form of (POSIX path of a_file)
				do shell script sh_script
			end if
		end repeat
		
		-- Get the current Trash size in 1k clusters, then divide by 1024 to get megabytes
		set trash_size to do shell script "du -sk ~/.Trash/ | awk '{print $1}'"
		set trash_size to trash_size / 1024
		
		-- Delete old items until we're under the limit
		repeat while trash_size is greater than trash_limit
			set trash_files to (list folder this_folder without invisibles)
			set oldest_file to {}
			
			-- Get the least recently deleted file in the Trash folder
			repeat with i from 1 to the count of trash_files
				set a_file to alias ((this_folder as text) & (item i of trash_files))
				if i is equal to 1 then set oldest_file to a_file
				if the (modification date of (info for a_file)) comes before (modification date of (info for oldest_file)) then set oldest_file to a_file
			end repeat
			
			-- Delete the file and update the Trash icon
			set sh_script to "rm -Rf " & quoted form of (POSIX path of oldest_file)
			do shell script sh_script
			
			-- And rinse!
			set trash_size to do shell script "du -sk ~/.Trash/ | awk '{print $1}'"
			set trash_size to trash_size / 1024
		end repeat
		tell application "Finder" to update trash
	end try
end adding folder items to


[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: aqsalter on Nov 11, '06 11:09:44PM
small problem... where it says

	-- Delete the file and update the Trash icon
	set sh_script to "rm -Rf " & quoted form of (POSIX path of oldest_file)
	do shell script sh_script
this will fail with no warning if you don't have permission to delete the file... it should read

	-- Delete the file and update the Trash icon
	set sh_script to "rm -Rf " & quoted form of (POSIX path of oldest_file)
	try
		do shell script sh_script
	on error
		display dialog "Permission denied on file " 
			& quoted form of (POSIX path of oldest_file) 
			& " would you like to try with administrator priviledges?"
		do shell script sh_script with administrator privileges
	end try


[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: mozart111 on Nov 07, '06 09:04:51AM

Why?



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: cougar718 on Nov 07, '06 09:36:24AM

I second that. Why? That's a disaster waiting to happen.

Hypothetical situation: Say you have selected a mix of files and directories that you wanted deleted but you happened to select a file that should not be deleted... If the size of this selection is greater than or equal to your size limit, those items will deleted and gone forever.

This happens all the time. Working too fast, not being careful, etc.

This is just 1 of many situations that make deleting trash automatically based on size a very bad idea.

---
Rick alias cougar



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: BMarsh on Nov 07, '06 12:29:57PM

many people I've done support, or training for empty the trash without thinking as it is, losing data sometimes.

for some users, this might actually reduce the risk to some extent.
and if you limit it to 5-10% of the total HD space, on most drives sold in the last 3 years, this is still at least 4+ GB in most cases.

I'll stick to my own method which is manual, emptying the trash once every few days unless I need the space back immediately. Gives me a couple of days to realize if I actually needed something or not.
But I'm keeping this on file, especially for recent windows converts.



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: carmst on Nov 07, '06 11:02:38AM

You don't have to remember to empty the trash manually; the trash now becomes a 2GB (or whatever) cache of your most recently deleted files.



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: DarkBlue on Nov 07, '06 09:18:33AM

This didn't work for me until I relaunched the Finder - this note might save others a little bit of hair pulling! :-)



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: AJB on Nov 07, '06 12:32:36PM

An interesting (but diminishing returns ?) enhancement to this would be to preserve the file modification date - because for metadata pedants, the file hasn't been modified just moved, and if you choose to restore the file from the trash then you have "corrupted" that metadata.

I can't think of any inherent "file moved" metadata off the top of my head (metadata geeks, feel free to pipe up) but one could use the generically extensible metadata now available, and add a "dateTrashed" attribute.



[ Reply to This | # ]
manually add the folder ~/.Trash
Authored by: beccles on Nov 07, '06 03:43:48PM
Translation: After clicking the Add folder + button, you'll see the Choose Folder sheet. In the search field start typing ~/.Trash. This will bring up the Go To Folder dialog box.

[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: astrosmash on Nov 07, '06 06:19:34PM

Great stuff. I've been meaning to do something like this for a while.



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: digitol on Nov 07, '06 06:25:51PM

Great hint thanks! Although just thought I would warn people that folder-action scripts can sometimes "leak" and use much of your processor, causing a slow computer. Just FYI.



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: aqsalter on Nov 07, '06 11:38:00PM

Does this work?
I used the updated script in the comments, but my trash doesn't seem to be reducing... I've got several large files in folders in the trash (ie not in the root of the trash...) would this affect it?

Thanks,
Adam



[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: aqsalter on Nov 11, '06 10:08:49PM

I had the same problem. I'm not sure what the problem was, but after relaunching the finder and editing and saving the script a few times it seems to be working...
Killed the "System Events" process too...
I have around 8gb of files so I think it may take a while to determine the oldest file.

Not sure.

-Adam



[ Reply to This | # ]
Question
Authored by: gshenaut on Nov 08, '06 07:35:42AM

Something I've wondered about is whether there is some way to empty the trash oldest-first and stop when it reaches a certain size. By oldest, I don't mean the age of the file, I mean the longest residence in Trash.

Probably a script that used ls -cr and du -s would do the trick, I haven't tried it. Ideally, this could be added to the "Actions" of all Trash folders. No idea how to do that.

Personally, I wouldn't want to make this or any other trash-emptying automatic; to me that defeats the idea of a trash can. But I would like it if there could be a bit more control over the emptying process.

Greg Shenaut



[ Reply to This | # ]
The opposite: A date-limited Trash can
Authored by: SeanAhern on Nov 09, '06 08:44:55PM
I use the opposite. I run a perl script that deletes anything from the ~/.Trash that's more than 2 weeks old. Running this once a day (with launchctl) ensures that my trash can never has really old things in it, but still provides me with the ability to recover from accidental deletions. The script is actually an extremely old perl script that I have never found a reason to change:
#!/usr/bin/perl

require "finddepth.pl";

# Traverse desired filesystems

&finddepth('/Users/ahern/.Trash/.');

exit;

sub wanted {
    (
        (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
        ! -d _ &&
        (int(-M _) > 14)
    ) &&
    unlink($_);

    rmdir $name if (-d _);  # Fails silently if directory has stuff in it.
}


[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: gjw on Nov 13, '06 01:43:55PM

(Disclosure: I'm the author of Compost.)

It should be noted that Compost:
a) Doesn't have the limitations you specifically note in your own solution.
b) Offers some additional configurability and functionality beyond the simple size limit on the trash can.

And in that context, I appreciate that you bothered to include the link.

I'm sincerely (because it does affect me) curious why "it costs money" was a problem and if you had suggestions about what might have mitigated that for you.



[ Reply to This | # ]
Updated script for Leopard
Authored by: carmst on Feb 10, '09 06:27:41AM
After I upgraded to OSX 10.5 I had to update this script, because 10.5 was killing it halfway through if too many small files were in the trash, probably due to too much disk I/O. The old version admittedly was grossly inefficient, so criticism accepted, Leopard. :)

The version below now only gets the size of the Trash folder once, instead of after every file is deleted. There's also some logging and a retry with admin privileges if a stubborn file fails to delete.


on adding folder items to this_folder after receiving added_items
	
	set sizeLimit to 2048
	
	try
		tell application "Finder"
			set theSize to (size of (this_folder)) / (1024 ^ 2)
			repeat with thisItem in added_items
				set modification date of thisItem to (current date)
			end repeat
		end tell
	end try
	logConsole("TrashControl: Trash is using " & theSize & " of " & sizeLimit & " MB.")
	
	do shell script "ls -tr " & (quoted form of (POSIX path of this_folder))
	set theFiles to paragraphs of result
	
	set i to 1
	repeat while theSize is greater than sizeLimit
		
		set oldestFile to alias ((this_folder as text) & (item i of theFiles))
		try
			set theSize to theSize - ((size of (info for oldestFile)) / (1024 ^ 2))
		end try
		
		logConsole("TrashControl: Deleting " & quoted form of (POSIX path of oldestFile))
		set sh_script to "rm -Rf " & quoted form of (POSIX path of oldestFile)
		try
			do shell script sh_script
		on error errmsg
			set dialogmsg to "File failed to delete. Retry as Admin?"
			display dialog dialogmsg
			do shell script sh_script with administrator privileges
		end try
		set i to i + 1
		
		logConsole("TrashControl: Trash is using " & theSize & " of " & sizeLimit & " MB.")
	end repeat
	
	logConsole("TrashControl: Trash is under control at " & theSize & " MB.")
end adding folder items to

on logConsole(logMsg)
	set shellCommand to "logger" & space & quoted form of logMsg
	do shell script shellCommand
end logConsole


[ Reply to This | # ]
An AppleScript to create a size-limited trash can
Authored by: bkhl on Oct 18, '10 07:16:45AM

Will this also be applied to external disks? If so, will it use the limit as a total for all disks, or for each disk separately. If it doesn't work on external disks, any ideas on how to get that going?



[ Reply to This | # ]