1

I transfer a lot of data to my Mac using SD cards from video and audio equipment. The SD cards are mounted as disks (or volumes, whatever you want to call them) and displayed on the Desktop. After uploading, I needed a way to empty the trash on the individual SD cards without emptying the trash on all disks so I used Script Editor to create the following app and saved it to the desktop as an app. This was created years ago and worked perfectly.

on open dropped_item
    tell application "Finder"
        -- get path to drive.
        set drivepath to POSIX path of dropped_item
    end tell
    if drivepath is "/" then
        display dialog "not allowed on the boot volume. Exiting"
    else
        set trashpath to drivepath & ".Trashes"
        set confirm to display dialog ¬
            "Empty the trash on " & drivepath & ¬
            "?" buttons {"No", "Yes"} default button "No"
        if button returned of confirm is "Yes" then
            do shell script "rm -rf " & trashpath
        end if
    end if
end open

I upgraded to Ventura a few months ago and the app appeared to work because there were no error messages, but I recently discovered that it was not deleting the trash. I gave the app, Script Editor, and Terminal Full Disk Access permission and this did not help. In fact, when I ran the app, the system revoked Full Disk Access for the app!!

When I tried some diagnostic edits and saved them, I started getting error messages (described below). It seems that scripts compiled by Monterey did not check for this error.

I stripped down the script to the following which demonstrates the root of the problem:

The following line is entered into Script Editor, compiled and saved as an app:

do shell script "rm -rf "/Volumes/SD_CARD_NAME/.Trashes"

Full Disk Access permission is given to Script Editor, the app, and Terminal.

If I run the script from Script Editor, .Trashes is removed

If I enter rm -rf /Volumes/SD_CARD_NAME/.Trashes in the Terminal command line, .Trashes is removed.

If I run the app by clicking on the icon for the app, .Trashes is not removed and I get the following error:

rm:/Volumes/SD_CARD_NAME/.Trashes: Operation not permitted (1)

and Full Disk Access for the app is disabled.

I tried several ways to solve this problem including the following:

tell application "Finder" delete folder "/Volumes/SD_CARD_NAME/.Trashes"

tell application "System Events" delete folder "/Volumes/SD_CARD_NAME/.Trashes"

And creating a shell script, saving it as an executable in ~/bin, giving it Full Disk Access permission, and calling that from the AppleScript. In this case, FDA was revoked for the app but not for the shell script in ~/bin.

None of these solved the problem.

I consider this a bug on several counts:

  1. Apple should not make it impossible to empty trash on a single volume. What horrible thing is going to happen if I remove trash on an SD card?
  2. The behavior is inconsistent between running the app from Script Editor and running it by clicking on it.
  3. The system should not revoke FDA without at least displaying an error message that tells me why and what I need to do to prevent the revoking.

I have filed a bug report, not that I expect Apple to fix the problem.

There have been several suggestions in the comments (thank you everyone who tried to help), but I've chosen a simple work around which is described in my "answer".

thanks again, to all.

Note: 2 October 2023
I just upgraded to Sonoma and had to change the script. If I delete .Trashes, the next time I try to drag a file into the trash, it says that the file will be permanently deleted. So I changed the script to get the UID and delete .Trashes/[UID]/* as shown below. (note there are many ways to write this script, mine is almost certainly not the best—script suggestions gratefully accepted)

#!/bin/csh -f
set X = `id | sed -r 's/uid=([0-9]*).*/\1/g'`
rm -rf .Trashes/$X/*

Note that if .Trashes/[UID] is empty you will get a harmless error message that rm could not find any files.

agarza
  • 2,274
dottore
  • 69
  • If there is more than just that statement, is the application code signed? – red_menace Apr 21 '23 at 03:31
  • Out of curiosity, why run an AppleScript to then run a shell command/script. Why not just run the script directly? – Allan Apr 21 '23 at 05:15
  • tbh, I'd never thought about this before, but if you use Image Capture's delete, the Trash doesn't fill up; in fact a .Trashes isn't even generated [though once you've generated a .Trashes by manually deleting, it then stays - just doesn't fill up].. – Tetsujin Apr 21 '23 at 05:40
  • red_menace -- yes, there is more code. I reduced it to that line because that's the heart of the problem. The script/app gets the volume name, displays it for me to verify, then constructs the line for the shell script. I don't know what you mean by "application code signed", sorry. – dottore Apr 21 '23 at 16:30
  • Allan - I did that way because it's a lot easier to just drop the icon for the SD card onto the app than to open a terminal window and type in the command. Also, if I type in the command I could easily make a mistake and remove important files. The script ensures that I only delete .Trashes on that volume. I sometimes deal with a dozen or more SD cards in one session. – dottore Apr 21 '23 at 16:34
  • tbh - I just looked at Image Capture and I don't see a delete command. I'd be happy to try it, could you give me more info on how to find and use that capability. One other issue is that I want to maintain recoverability of all the files on a card until I'm done processing that card. – dottore Apr 21 '23 at 16:36
  • sorry, I meant to address that the comment about Image Capture to Tetsujin. – dottore Apr 21 '23 at 17:02
  • I would bet that you are having this issue because the UUID of the folder is different for each SD card even though the name is the same. When you run you Apple Script, it’s basically telling you that your “security settings” are no longer valid because it’s a different folder. – Allan Apr 21 '23 at 21:37
  • Allan - interesting comment, thanks. Though I'm not exactly sure if it applies or what to do with it. When the full script is run, the volume name of the SD card is a dropped item, so the name is different for each card. The code I put in the post was a reduction to the simplest form of the problem. The app gets the volume name like so: on open dropped_item set drivepath to POSIX path of dropped_item – dottore Apr 21 '23 at 22:33
  • The reason the app permissions are getting removed is that AppleScript normally saves properties and globals by modifying the file. This causes the system to see the application as another one - one that has not been given permission. Code signing the app (you can create your own certificate) or making the script file read only will stop that. – red_menace Apr 22 '23 at 23:48
  • red_menace. Thanks for this. I'm totally new to code signing but I took a quick look and it seems to be more for apps that are distributed over the web???? Here's a quote from a description of code signing: Code signing is required by Apple for integrating app services, installing your macOS app on another machine or uploading it to distribute it through the Mac App Store or outside of Mac App Store. It enables to identify who developed the app and ensure that all the changes to the app come from you or your team. I'll look at it more thoroughly tomorrow. – dottore Apr 23 '23 at 03:24
  • red_menace - I just tried making the app read only. I changed all the files in rmTrash.app/Contents to read only. no effect. FDA is still revoked when I run the app. Is there something else I need to do? – dottore Apr 23 '23 at 03:32
  • To get full file permissions, you can use "bypass" (explained here) , this is for Terminal but it might give you a clue. PS : Do not forget to include a "@" before the username of people to get them notified :) – Thinkr Apr 23 '23 at 07:14
  • Thinkr -- thanks for the tip. I just looked for TMSafetyNet.kext and I can't find it in the location given in the reference: /System/Library/Extensions. I also searched for it, and couldn't find it. I am running Ventura 13.3.1, what OS are you running? Or did I misinterpret something in the referenced post? – dottore Apr 23 '23 at 15:41

1 Answers1

1

This is the simplest solution I could find.

  1. Create the following executable shell script:
    cd ~/bin
    cat "rm -rf .Trashes" > rmtrash
    chmod +x rmtrash
    
  2. Give Full Disk Access permission to Terminal and to rmtrash
    System Settings->Privacy & Security->Full Disk Access
    Enable Terminal
    click + (at bottom of screen)
    search for rmtrash and add it
    enable rmtrash
    

To empty trash on an SD card (or any volume for that matter)

right click on the volume
Select New Terminal at Folder
type rmtrash

Note, if you have a multi user system you could get the UID and add it to the rm command, but in my case the system is single user and I only use this on SD cards, so I keep it simple.

I've requested that Apple add a "empty trash on one volume" command, but I have little hope of ever seeing it.

PS. I tried the rmtrash script on a partition of the internal disk and I got "permission denied". I was able to manually delete the trashes but I had to use sudo to do it. Apple's protection for the internal disk is higher, even partitions of that disk that are not actually the boot volume. I think that is a good decision on Apple's part.

dottore
  • 69
  • 1
    Why not just script the system to empty the trash? Seems fairly convoluted for the payoff but perhaps I am missing your constraint from the long question. – bmike Apr 23 '23 at 19:10
  • what do you mean by "script the system?" There's a work flow that is too complicated to describe here, but bottom line is I need to be able to delete trash on a volume when I'm ready to delete it and the temporary storage in .Trashes is important. Besides, couldn't I still have the permissions problem no matter how I did it? – dottore Apr 24 '23 at 16:02
  • It's a one liner command line executed AppleScript - osascript -e 'tell app "Finder" to empty' or perhaps this useful tool? – bmike Apr 24 '23 at 18:11
  • thanks, something like that could work. Remember that I need to empty the trash from one and only on disk/sd-card. so something like Tell Finder to empty trash is not what I need as it will empty trash from all volumes. And creating another script using "osascript -e ...." still requires me to open a Terminal window. The useful tool you mentioned is a good one for multi-user situations or where you need to be careful about what gets deleted. thanks. – dottore Apr 24 '23 at 23:07