Quando un'app Mac non si disinstalla: sette cause, un sintomo ciascuna
Una disinstallazione fallita su macOS non è un solo problema. Il Finder può rifiutarsi di spostare il bundle. Lo spostamento può riuscire e l'app può tornare al login successivo. Il bundle può sparire mentre l'helper che ti dava fastidio continua a girare. Ognuno è un meccanismo diverso con una soluzione diversa, quindi parti dalla cosa esatta che ha fatto il tuo Mac. Per la sequenza ordinaria, vedi disinstallazione completa; quello che segue presume che sia già fallita.
Parti dal sintomo
- "L'elemento non può essere spostato nel Cestino perché è aperto." Qualcosa è in esecuzione, spesso non l'app che hai chiuso.
- È stata cancellata, ed è tornata. Un job launchd, un profilo, o un package manager l'ha rimessa a posto.
- Il Finder chiede una password di amministratore. Un
.pkgha lasciato il bundle posseduto da root. Normale. - Non succede niente. Nessuna finestra, nessun errore. Il permesso Gestione app è negato.
rmcome root dice "Operation not permitted". System Integrity Protection.- In grigio, o riappare su un Mac di lavoro. Un profilo di configurazione o MDM lo possiede.
1. L'app, o uno dei suoi helper, è ancora in esecuzione
Il Finder si rifiuta di spostare un bundle i cui file sono aperti, e chiudere il processo
che vedi non ferma tutto ciò che l'app ha avviato. Monitoraggio Attività elenca ogni
processo, non solo quelli con una finestra. Cerca il nome del fornitore e leggi l'intero
insieme di risultati: un'app chiamata Foo di solito spedisce Foo Helper, un
FooUpdater, e un bundle da login item con un nome visualizzato senza relazione. La
finestra menu Apple > Uscita forzata non è un sostituto, perché elenca solo le
applicazioni con una presenza UI.
pgrep -fl -i foo
lsof +D /Applications/Foo.app 2>/dev/null | awk '{print $1, $2}' | sort -u
pgrep -fl confronta l'intera riga di comando, quindi cattura un helper il cui percorso
eseguibile porta il nome del fornitore anche quando il suo nome di processo non lo fa.
lsof +D riporta ogni processo che tiene aperto un file dentro il bundle.
Forzare la chiusura del genitore non ferma in modo affidabile un helper. Un helper è un proprio processo con un proprio PID, quindi terminare il genitore lo orfanizza a meno che il genitore non lo smonti all'uscita. E se launchd gestisce l'helper, terminare l'uno o l'altro dice solo a launchd di riavviarlo. Questa è la prossima sezione.
Un'anteprima Quick Look o l'indicizzazione Spotlight possono anch'esse tenere file nel bundle, e un riavvio pulisce entrambi. Se il messaggio torna, la guida alla rimozione app di Apple suggerisce la Modalità sicura.
2. Un agent o daemon launchd la riporta indietro
Questo è il caso "l'ho cancellata ed è tornata", e il più spesso diagnosticato male: la gente controlla Monitoraggio Attività, non vede niente, e conclude che l'app non era in esecuzione. L'avvio su richiesta significa che non è una prova.
launchd supervisiona i lavori in background. Un job è una property list con una Label,
un programma, e condizioni per eseguirlo. RunAtLoad lo avvia quando il job si carica,
KeepAlive lo riavvia quando esce. Un job senza nessuno dei due torna comunque:
MachServices, Sockets, WatchPaths, QueueDirectories, e StartInterval fanno tutti
sì che launchd avvii il processo nel momento in cui qualcosa lo richiede, quindi un helper
che resta inattivo dopo dieci secondi e riparte sul suo servizio Mach sembra assente ogni
volta che controlli.
Le definizioni vivono in tre posti. ~/Library/LaunchAgents è solo il tuo utente, dentro
la tua sessione di login; /Library/LaunchAgents gira per ogni utente al login; e
/Library/LaunchDaemons gira a livello di sistema come root prima che chiunque acceda, ed
è per questo che un daemon sopravvive a una disinstallazione manuale mentre un agent spesso
no. /System/Library/Launch* è di Apple e protetto.
launchctl list | grep -i foo
launchctl print-disabled gui/$(id -u) | grep -i foo
grep -l -i foo ~/Library/LaunchAgents/*.plist /Library/LaunchAgents/*.plist \
/Library/LaunchDaemons/*.plist 2>/dev/null
In launchctl list, una label con un PID è in esecuzione ora e una con un trattino è
caricata e in attesa di un trigger; print-disabled legge il database di stato
disabilitato persistente, un fatto separato da se un plist esiste. Leggi il candidato con
plutil -p <path> e controlla che Program o ProgramArguments punti all'app che stai
rimuovendo: i fornitori non sempre chiamano il file come la label al suo interno.
L'ordine conta
Ferma e disabilita il job per primo, poi rimuovi il plist, poi rimuovi l'app.
launchctl bootout gui/$(id -u)/com.vendor.foo.helper
sudo launchctl bootout system/com.vendor.foo.daemon
launchctl disable gui/$(id -u)/com.vendor.foo.helper
Cancella il plist mentre il job è caricato e launchd mantiene un servizio la cui definizione non esiste più su disco; gira fino al prossimo riavvio e può lasciare una voce obsoleta nel database di stato disabilitato. Rimuovere prima l'app è peggio: il job rinasce contro un eseguibile mancante e fallisce in loop, ed è da lì che viene "è sparita ma appare ancora negli Elementi login".
Su macOS 13 e successivi, le app si registrano tramite
SMAppService
e quelle registrazioni vivono dentro il bundle app, quindi potrebbe non esserci alcun
plist da trovare. Quelle appartengono alla Gestione attività in background, controllata in
Impostazioni di Sistema > Generali > Elementi login ed estensioni
(guida agli elementi di avvio).
3. È un'app di sistema protetta da SIP
System Integrity Protection è una policy a livello kernel, non un bit di permesso. Apple
la descrive come l'uso di permessi kernel per limitare la scrivibilità dei file di sistema
critici, applicata "to every process running on the system, regardless of whether that
process is running sandboxed or with administrative privileges"
(Apple Platform Security).
Da Big Sur il contenuto di sistema sta anche su un volume separato, sigillato
crittograficamente. csrutil status stampa se la protezione è attiva, e Apple è esplicita
che "you can't remove apps that are required by your Mac", un insieme che include Mail,
Musica, Libri, Note, Podcast, Mappe, News e Borsa.
Disattivare SIP per cancellare un bundle è un cattivo scambio. Significa avviare in Recovery e cambiare una policy di sicurezza a livello di macchina; sui Mac Intel, Apple nota che disattivarla rimuove la protezione per ogni partizione sul dispositivo di storage fisico, e su Apple silicon il Mac esce da Sicurezza completa. Il vantaggio non dura nemmeno: il volume di sistema viene sostituito interamente al prossimo aggiornamento macOS, e non viene recuperato spazio utilizzabile.
Meglio: trascina l'icona fuori dal Dock, rimuovila da Impostazioni di Sistema > Generali > Elementi login ed estensioni, e se continua ad aprire i tuoi file, cambia il gestore con Ottieni informazioni > Apri con > Cambia tutti.
4. È stata installata da MDM o un profilo di configurazione
Su un Mac gestito un'app può essere rispedita secondo il programma del server di gestione, e un profilo può essere segnato come non rimovibile. I sintomi sono una rimozione che si annulla da sola ore dopo, un controllo in grigio, o una ricerca launchd che non trova niente perché la reinstallazione è guidata da remoto. Controlla Impostazioni di Sistema > Generali > Gestione dispositivo; se quella sezione è assente, il Mac non è gestito e non è questa la tua causa.
profiles status -type enrollment
sudo profiles list
Il primo riporta l'iscrizione tramite Automated Device Enrollment e se è approvata dall'utente; il secondo elenca i profili installati e serve root. Poi chiedi all'IT. Le indicazioni di Apple sono di chiedere a chi ha fornito un profilo che non riesci a rimuovere, e avvertono che rimuovere un profilo cancella tutto ciò che quel profilo configurava, quindi uno che porta il tuo account mail lo porta via con sé.
5. Proprietà, e il permesso che fallisce in silenzio
Il Finder chiede una password di amministratore. Normale. Un installer .pkg gira
come root e lascia il bundle posseduto da root, quindi spostarlo richiede
autenticazione. Conferma con ls -ld /Applications/Foo.app. Le ricevute vale la pena
conoscerle ora che ci sei: pkgutil --files <id> elenca i percorsi che un pacchetto ha
piazzato, e sudo pkgutil --forget <id> scarta la ricevuta da
/private/var/db/receipts senza cancellare un singolo file.
Non succede niente del tutto. Nessun prompt, nessun errore, l'app è ancora in
/Applications, e lo strumento che hai usato riporta un fallimento vago o ripiega su
qualcos'altro. Su macOS 14 e successivi di solito è Gestione app, che Apple descrive come
"Allow apps to update or delete other apps on your Mac". L'indizio è che il percorso è
scrivibile POSIX e la scrittura fallisce comunque:
test -w /Applications/Foo.app && echo "posix says yes"
Se questo stampa e la rimozione ancora non avviene, i permessi non sono il tuo problema. Vai a Impostazioni di Sistema > Privacy e sicurezza > Gestione app, abilita l'app che fa la rimozione, poi riavviala, perché molte app consultano il permesso solo all'avvio.
Sotto il cofano: tre rifiuti che sembrano uguali
I permessi POSIX sono il primo cancello: il bundle è posseduto da root, tu non lo sei, e
sudo lo risolve, perché il controllo riguarda solo quale utente sei. TCC, il livello
privacy dietro Impostazioni di Sistema, decide dopo che POSIX passa. Gestione app è un
cancello TCC per un'operazione, modificare o cancellare il bundle di un'altra app. Essere
amministratore non lo soddisfa e nemmeno sudo, perché è legato al programma richiedente
piuttosto che all'utente, ed è per questo che il suo rifiuto può manifestarsi come un
errore generico senza alcun prompt.
SIP sta sotto entrambi e rifiuta root del tutto. Un rifiuto POSIX imposta EACCES e
stampa Permission denied; un rifiuto SIP imposta EPERM e stampa Operation not
permitted. Il primo significa riprova con autorità, il secondo significa che non c'è
autorità con cui riprovare.
6. Un'estensione di sistema o un filtro di rete è ancora attivo
Software di sicurezza, client VPN e prodotti di virtualizzazione installano estensioni di sistema. Il bundle app registra l'estensione; non è l'estensione. Cancella il container mentre l'estensione è attiva e la registrazione resta senza proprietario, ed è così che un Mac continua a filtrare il traffico attraverso software che credi di aver rimosso.
systemextensionsctl list
L'output mostra identificativo di team, bundle identifier, e uno stato come
[activated enabled]. La disattivazione appartiene all'app contenitrice e spesso richiede
un riavvio, quindi esegui prima l'uninstaller del fornitore.
Disinstallare un antivirus su Mac copre l'ordine
di smontaggio per questa classe.
7. Proviene dall'App Store, o da Homebrew
App dal Mac App Store. Cancellare il bundle non rimuove l'acquisto. Il caso che coglie la gente è l'impostazione che Apple descrive come "Automatically download apps that you purchased from the App Store on other Mac computers and devices": se un secondo Mac sullo stesso account ce l'ha ancora, quell'impostazione può riportarla indietro. Disattivala in App Store > Impostazioni.
Cask Homebrew. Se hai installato con brew install --cask foo, cestinare l'app lascia
Homebrew a credere che sia installata. brew list --cask mostra ancora il token, e il
prossimo brew upgrade può reinstallare l'app che hai appena cancellato, una causa reale
di "è tornata" senza alcun job launchd coinvolto. Esegui invece
brew uninstall --cask foo. La pagina man di Homebrew descrive --zap come la rimozione
di "all files associated with a cask" e avverte che "may remove files which are shared
between applications", quindi usa quell'opzione deliberatamente.
Dopo una cancellazione riuscita: cosa resta
Elementi login ed estensioni la elenca ancora. O una voce "Apri al login" che punta a un percorso mancante, o una voce di Gestione attività in background per un servizio il cui programma è sparito. Rimuovila con il pulsante meno in Impostazioni di Sistema > Generali > Elementi login ed estensioni; macOS spesso le ripulisce da solo dopo un riavvio.
Un'icona nella barra dei menu appare all'avvio. Qualcosa carica ancora un binario:
di solito un launch agent che non hai mai rimosso, o un helper che l'installer ha copiato
dentro ~/Library/Application Support/<vendor>.
Un helper privilegiato sopravvive. Software che richiedeva root si installa in
/Library/PrivilegedHelperTools/<label> con un
/Library/LaunchDaemons/<label>.plist corrispondente. Entrambi sono posseduti da root e
fuori dal bundle, quindi cestinare l'app non tocca nessuno dei due.
ls -la ~/Library/LaunchAgents /Library/LaunchAgents /Library/LaunchDaemons \
/Library/PrivilegedHelperTools 2>/dev/null
Per il lato dati, vedi file residui dopo la disinstallazione.
Fare questa diagnosi in Mole
La versione manuale di questo articolo costa cinque schermate: Monitoraggio Attività, tre cartelle launchd, Elementi login ed estensioni, Privacy e sicurezza, e Finder. Mole mette le parti che appartengono a un'app su una sola scheda, e la scansione è sempre gratuita, quindi funziona come diagnostica in sola lettura che tu la compri o no.
Apri la scheda Software di Mole. Contiene tre segmenti: l'inventario delle app installate, gli aggiornamenti disponibili, e gli elementi di avvio. Quest'ultimo è l'inventario launchd e login item che questo articolo ti ha detto di assemblare a mano, così la causa "torna indietro" è visibile prima che tu cancelli invece che dopo.
Seleziona un'app e Mole ne risolve il bundle identifier, poi trova cosa possiede quella identità: Application Support, Caches, Preferenze, Container, HTTPStorages, e launch agent o daemon il cui plist referenzia davvero l'app piuttosto che condividere semplicemente una parola con il suo nome. Ogni candidato porta il suo percorso, la sua dimensione, e la prova che l'ha collegato, e qualsiasi cosa a bassa confidenza arriva deselezionata.
Confermare esegue l'ordine che questo articolo raccomanda, applicato invece che ricordato.
Mole chiude l'app e gli helper annidati dentro il suo bundle, disattiva i suoi helper
login item, scarica ogni elemento launch approvato tramite launchctl prima che il suo
plist venga rimosso, e valida ogni percorso di nuovo al momento della cancellazione. Le
rimozioni vanno nel Cestino, quindi un errore è un trascinamento fuori.
Poi Mole riporta gli elementi saltati e falliti con i loro percorsi invece di un totale di
successo, così una riga rifiutata perché Gestione app è negata, o perché un percorso è
posseduto da root e la protezione l'ha respinta, ti dice quale causa sopra hai appena
incontrato. Uno strumento che stampa un segno di spunta su una scrittura rifiutata è il
motivo per cui la gente passa una serata a chiedersi di un'icona nella barra dei menu.
Tutto ciò che fa Mole gira in locale, e le operazioni sui file vengono aggiunte a
~/Library/Logs/mole/operations.log. In un terminale,
Mole CLI è gratuito e open source, e mo uninstall
accetta --dry-run così puoi leggere la lista dei percorsi prima.
Mole non combatte le tre cause che non può vincere: non disattiverà SIP né rimuoverà un'app Apple di serie dal volume sigillato, non può scavalcare un profilo di configurazione che reinstalla software su un Mac gestito, e per agent di sicurezza, client VPN e prodotti di virtualizzazione non è un sostituto dell'uninstaller del fornitore che conosce l'ordine di smontaggio. Quando Gestione app è negata, Mole riporta il fallimento invece di scavalcare i privilegi.
Domande frequenti
Perché un'app torna dopo che l'ho cancellata?
Quattro cause, in ordine approssimativo di frequenza. Un agent o daemon launchd ha ancora
una definizione di job che punta ad essa e la riavvia a un trigger che non puoi vedere in
Monitoraggio Attività. Una voce di cask Homebrew è sopravvissuta perché hai cestinato l'app
invece di eseguire brew uninstall --cask. Su un Mac gestito, l'MDM l'ha rispedita
indietro. O l'impostazione dell'App Store per scaricare automaticamente le app acquistate
sui tuoi altri dispositivi l'ha tirata da un secondo Mac.
Posso cancellare le app integrate di Apple se disattivo SIP?
Tecnicamente sì, ed è un cattivo scambio: un downgrade della sicurezza a livello di macchina fatto da Recovery, in cambio di un bundle che torna al prossimo aggiornamento macOS quando il volume di sistema sigillato viene sostituito. Rimuovila dal Dock e dagli Elementi login invece.
Il Finder chiede la mia password per cancellare un'app. C'è qualcosa che non va?
No. Un installer .pkg ha messo lì il bundle come root, quindi spostarlo richiede
autenticazione. Il fallimento che vale la pena preoccuparsi è l'opposto: nessun prompt,
nessun errore, niente succede. Di solito è Gestione app negata sotto Impostazioni di
Sistema > Privacy e sicurezza, e sudo non lo risolve, perché il cancello è legato al
programma che chiede piuttosto che all'utente.
Approfondimenti correlati
- Come disinstallare completamente le app su Mac per la sequenza normale e i livelli di Library che rivede.
- Come disinstallare un antivirus su Mac per software con estensioni di sistema, dove l'ordine di smontaggio è tutto il lavoro.
- Come disattivare i programmi di avvio su Mac per il lato launchd ed Elementi login una volta che niente ti sta più combattendo.