In che modo rm -r procede alla rimozione ricorsiva? In quale ordine?


30

Esiste un ordine delle operazioni rm? Mi sono esibito rmsu una directory di grandi dimensioni e sono curioso di sapere dove avrei dovuto vedere cosa avrebbe potuto essere eliminato. Funziona rmprima sui file, quindi sulle directory? Oppure si basa su alcune informazioni nella tabella degli inode?

Specifiche: rm dal sistema GNU coreutils 8.22: Arch Linux in esecuzione su un filesystem beagleboneblack su cui operava era un HDD Seagate esterno (ext4) che utilizzava USB 2.0.

backstory:

Stavo eseguendo un po 'di pulizia della directory ed eseguito

cp -r A/ B/ C/ Dest/

Senza volerlo, l'ho seguito con

rm -r A/ B/ C/ Dest/

quando intendevo semplicemente esibirmi

rm -r A/ B/ C/

L'ho preso e ho premuto Ctrl+ Cprima che fosse passato troppo tempo. In particolare, sono stati <3 secondi mentre stavo usando il timecomando insieme a rm& cp. Entrai ed esaminai Dest/aspettandomi che fosse inesistente, ma ecco, era tutto intero e sembrava non esserne influenzato. Questo è un po 'sorprendente perché A/ B/ C/era piuttosto piccolo. Forse 100-200 MB in totale. Dest/tuttavia, è solo timido di 1 TB. L'esecuzione di un lsDest / ha mostrato che c'erano entrambi i file e le directory ad entrambe le estremità dell'alfabeto (ad esempio AFile.txt.... .... Zoo.txt).

Sono stato fortunato e ho cancellato rmprima che causasse il caos nella mia directory Dest /? È rmdavvero così lento (per fortuna!)?

In caso contrario, come si fa rma rimuovere in modo ricorsivo cose tali da indovinare cosa si sarebbe potuto perdere?

Non mi aspetto davvero di recuperare ciò che avrei potuto perdere, solo curioso di sapere cosa potenzialmente è stato spazzato via.


Risposte:


34

rm -rfunziona a turno su ciascuno dei suoi argomenti. Se un argomento è una directory, elenca la directory (con le funzioni opendire readdiro un metodo equivalente) e opera a turno su ciascuna voce. Se una voce è una directory, esplora quella voce in modo ricorsivo.

Questo è esattamente lo stesso metodo che altre applicazioni usano per attraversare le directory ricorsivamente - find, ls -Rf, etc.

L'ordine di attraversamento è imprevedibile. Sulla maggior parte dei filesystem, l'ordine è riproducibile fintanto che nessun file viene aggiunto, rimosso o rinominato nella directory (in teoria l'ordine potrebbe essere completamente casuale e cambiare ogni volta, ma non riesco a pensare a un filesystem in cui ciò accade). Su alcuni filesystem, l'ordine può in genere essere dedotto dai nomi dei file o dall'ordine in cui sono stati creati i file o da una combinazione di entrambi, ma è necessario conoscere i dettagli del filesystem e potrebbe variare a seconda del la versione del driver. L'ordine di attraversamento non è qualcosa su cui puoi fare affidamento.

Nota lso echo *ordina i file in ordine lessicografico dei loro nomi. finde ls -fnon ordinare.

L'unica cosa su cui puoi fare affidamento è che gli argomenti sono gestiti in ordine. Quindi, se C/fosse ancora parzialmente lì, significherebbe che Dest/non è stato toccato. Se non C/c'è più, puoi avere un'idea di dove sono stati rimossi i file Dest/controllando i tempi di modifica della directory e confrontandoli con il tempo è C/stato eliminato o il tempo in cui la copia è terminata. Il primo file da cancellare potrebbe essere un file direttamente Dest/o da qualche parte nel profondo della gerarchia a seconda che la prima voce Dest/che rmè successo a traverso era una directory o no.

La velocità di rmdipende principalmente dal numero di file da eliminare. Ci vuole un file molto grande per avere un notevole impatto sul tempo di eliminazione. La maggior parte del lavoro sta eliminando a turno ciascuna voce della directory. I dati del file non vengono cancellati, la cancellazione del contenuto di un file richiede solo di contrassegnare i blocchi che stava usando come gratuiti, il che è relativamente veloce.


2
L' -fopzione di lsè documentata come equivalente a -aU, dove -asignifica elencare tutti i file e -Usignifica non ordinati. Ricordo vagamente di aver incontrato una versione lsin cui -fnon funzionava (penso che fosse definito per essere qualcos'altro) ma funzionava -aU.
G-Man dice "Reinstate Monica" il

2
@ G-Man POSIX definisce -f(come estensione XSI ); ha davvero altri effetti oltre a quelli non ordinati. Risale al V7, quindi sarebbe difficile trovare un'implementazione senza di essa, a parte, stranamente, BusyBox. -Upoiché solo non ordinata è una funzionalità GNU, non penso che esista altrove.
Gilles 'SO- smetti di essere malvagio' il


@Tim No. È possibile eseguire il test eseguendo ls -Uin una directory. Questo è lo stesso ordine in cui rm -rfunzionerebbe in quella directory. Si noti che l'aggiunta o la rimozione di un file può modificare l'ordine degli altri file.
Gilles 'SO- smetti di essere malvagio' il

Grazie. (1) "l'aggiunta o la rimozione di un file può cambiare l'ordine degli altri file.", Quindi dopo una rimozione parziale accidentale, ls -Unon aiuta a scoprire se le directory sopravvissute non sono state toccate? (2) -U significa "elenca le voci nell'ordine della directory". -U indica l'ordine delle voci di directory nella directory?
Tim

5

Come dice Gilles, in genere non è possibile prevedere l'ordine delle eliminazioni all'interno di una directory, solo che le directory di livello superiore verranno elaborate nell'ordine dalla riga di comando.

Tuttavia, sei anche sicuro che eliminerà le gerarchie di directory dal basso verso l'alto, perché Unix consente di eliminare le directory solo se sono vuote. Quindi, per eliminare una directory, deve prima rimuovere tutto ciò che contiene. Se contiene sottodirectory, deve prima rimuovere il loro contenuto e così via.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.