GNU/Linux >> Linux Esercitazione >  >> Linux

'rm .*' elimina mai la directory principale?

L'espressione .* viene ampliato da bash per includere le directory corrente e padre:

$ ls -la
total 2600
drwxrwxrwx   2 terdon terdon 2162688 Sep 10 16:22 .
drwxr-xr-x 142 terdon terdon  491520 Sep 10 15:34 ..
-rw-r--r--   1 terdon terdon       0 Sep 10 16:22 foo
$ echo .*
. ..

Se eseguo rm -rf .* sulla mia Debian usando GNU bash, version 4.2.36(1)-release e rm da rm (GNU coreutils) 8.13 , ricevo questo messaggio:

$ rm -rf .*
rm: cannot remove directory: `.'
rm: cannot remove directory: `..'

È una cosa GNU o è POSIX? Ci sono sistemi *nix in cui il comando sopra eliminerà silenziosamente . e .. ?

Inoltre, è una caratteristica di sicurezza della shell o di rm comando stesso?

Risposta accettata:

L'ultima versione (a partire dal 2017) delle specifiche POSIX per rm l'utilità è qui (e quella precedente lì) e vieta la cancellazione di . e .. .

Se uno dei file punto o punto-punto è specificato come parte del nome di base di un operando (ovvero, il componente del percorso finale) o se un operando si risolve nella directory principale, rm scriverà un messaggio diagnostico di errore standard e non farà nulla di più con tali operandi.

Come notato da @jlliagre, la parte su / è un'aggiunta in SUSv4.

La più vecchia specifica Unix disponibile pubblicamente che sono riuscito a trovare (XPF4 CAE rev2 (1994)), ha già specificato che . e .. non può essere rimosso, anche se i commenti nel log delle modifiche di GNU fileutils suggeriscono che era già il caso delle specifiche POSIX precedenti.

Nota che si applica a dir/.. e ../ anche, ma alcune implementazioni (incluse quelle certificate UNIX come Solaris 11 e macOS) non garantiscono ancora rm -rf ../ o rm -rf .*/ ).

storia

Le prime unice

Il -r opzione per rm è stato aggiunto in Unix V3 (1973) anche se eliminava solo il contenuto delle directory, dovresti comunque usare rmdir per rimuovere le directory.

Ciò è cambiato in Unix V7 (1979, la versione che ha introdotto anche la shell Bourne e da cui deriva la maggior parte degli Unice). rm -r ora rimuoveva anche le directory e non cancellerebbe il .. albero di directory. La pagina man afferma:

È vietato rimuovere il file .. semplicemente per evitare le conseguenze antisociali di fare inavvertitamente qualcosa come rm -r .* .

(sebbene si possa obiettare che rm -r .* è ancora antisociale poiché elimina tutto perché . è incluso).

Ha comunque accettato di rimuovere . anche se non scollegherebbe il . o .. inserimenti. Quindi, rm -r . era un modo efficace per svuotare la directory corrente.

Nota anche che la protezione era solo per un letterale .. argomento, non per dir/.. o ./.. . Quindi, rm -rf ./.* rimuoverebbe comunque tutto nella directory principale in modo ricorsivo.

È interessante vedere che questo era già un modo per aggirare il bug/funzionamento errato per cui i glob potevano includere . e .. nella loro espansione. Questo è stato risolto nella shell Forsyth (la base per la shell Minix originale e pdksh) alla fine degli anni '80, zsh (1990) e fish (2005) ma non altre shell e in particolare non POSIX sh lingua che richiede l'espansione di .* per includere . e .. se vengono restituiti da readdir() (bash risolve il problema in parte solo con shopt -s dotglob dove glob (tranne .xxx quelli) non includono . o .. e con ksh , puoi risolverlo facendo FIGNORE='@(.|..)' ).

Correlati:come eliminare un file utilizzato da un altro processo?

Quando vieta esattamente . inoltre è stato aggiunto che non è sempre chiaro e varia con ogni Unix. Alcuni risultati di seguito.

BSD

Il divieto di . è stato aggiunto tra 2.9BSD (1983) e 2.10BSD (1987) e tra 4.2BSD (1983) e 4.3BSD (1986) (vedi questa modifica con timestamp 1985 in unix-history-repo).

$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9BSD/root.tar.gz |
    zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `..'
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.10bsd.tar.gz |
    zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `.' or `..'
rm: cannot remove `.' or `..'n");

Per dir/. e dir/.. , vedi questa modifica nel 1988 (BSD 4.3 Net/1).

Ad oggi, il rm di FreeBSD (e derivati ​​come macOS) svuota ancora la directory corrente o genitore su rm -rf ./ o rm -rf ../ benchè (importa per rm -rf .*/ ).

Sistema V

Non ho molte informazioni in quanto né il codice sorgente né il file binario sono pubblicamente disponibili per i derivati ​​AT&T Unix dopo la V7. Nel suo manuale online, HPUX (basato su System III) menziona ancora che proibisce solo .. mentre effettivamente proibisce entrambi, il che indica che probabilmente almeno SysIII non ha proibito la cancellazione di . (modifica :Ora guardando il SysIII rm codice sorgente, è praticamente invariato rispetto a Unix V7).

Tutti gli altri manuali online che ho controllato menzionano l'eliminazione di . o .. è vietato che dovrebbe essere conforme a POSIX.

Solaris rm svuota ancora la directory corrente o principale su rm -rf ./ o rm -rf ../ .

GNU

Il registro delle modifiche iniziale per le utility file GNU contiene tutte le informazioni storiche.

Mentre originariamente non si eliminava . o .. erano vietati, .. è stato vietato prima e poi entrambi (incluso dir/. ), tutti tra il 1990 e il 1991.

altro

Come abbiamo visto, in zsh , l'espansione di .* (o qualsiasi globo) non include mai . o .. (anche in sh modalità di emulazione). Il rm builtin (che ottieni se zmodload zsh/files ) pertanto non tratta . o .. appositamente. Quindi, con quel zsh integrato, puoi rm -rf . o rm -rf .. per svuotare . o .. , ma rm -rf .* non rimuoverà . o .. .

Nella casella occupata rm , il divieto di cancellazione di . e .. è stato aggiunto in 0,52 (2001)


Linux
  1. Rsync sta cambiando le autorizzazioni della directory?

  2. Eliminare la directory padre (non vuota) se una directory figlio specifica è vuota?

  3. 5 esempi pratici per eliminare/rimuovere directory in Linux

  4. Rimuove un collegamento simbolico a una directory

  5. Cosa significa opt (come nella directory opt)? È un'abbreviazione?

Come rimuovere (eliminare) un file o una directory in Linux

Come rimuovere una directory in Linux

Come rimuovere (eliminare) la directory in Linux

Rimuovi directory in Linux - Come eliminare una cartella dalla riga di comando

Come contare il numero di file in una directory ed eliminare il più vecchio se il numero supera 5?

Come eliminare domini/sottodomini nel cPanel?