L'ultima versione (a partire dal 2017) delle specifiche POSIX per l' rm
utilità è qui (e la precedente lì ) e proibisce la cancellazione di .
e ..
.
Se uno dei file punto o punto-punto viene specificato come parte del nome di base di un operando (ovvero il componente nome percorso finale) o se un operando si risolve nella directory principale, rm deve scrivere un messaggio diagnostico in errore standard e non fare nulla più con tali operandi.
Come notato da @jlliagre, la parte su /
è un'aggiunta in SUSv4.
Le più vecchie specifiche Unix disponibili pubblicamente che sono riuscito a trovare ( XPF4 CAE rev2 (1994)), lo hanno già specificato .
e ..
non possono essere rimosse, anche se i commenti nel file di logutils GNU suggeriscono che era già il caso nelle precedenti specifiche POSIX.
Si noti che si applica a dir/..
e ../
pure, ma alcune implementazioni (anche UNIX-certificate come Solaris 11 e MacOS) ancora non fare salvaguardia contro rm -rf ../
o rm -rf .*/
).
storia
Unici primi
L' -r
opzione a è rm
stata aggiunta in Unix V3 (1973) anche se stava solo cancellando il contenuto delle directory, dovresti comunque utilizzare rmdir
per rimuovere le directory.
Ciò è cambiato in Unix V7 (1979, il rilascio che ha anche introdotto la shell Bourne e da cui deriva la maggior parte degli Unices). rm -r
ora rimosso anche le directory e non eliminerebbe l' ..
albero delle directory. La pagina man afferma:
È vietato rimuovere il file ..
semplicemente per evitare le conseguenze antisociali di fare inavvertitamente qualcosa del genere rm -r .*
.
(anche se si potrebbe sostenere che rm -r .*
è ancora antisociale in quanto elimina tutto perché .
è incluso).
Ha comunque accettato di rimuovere .
sebbene non scollegasse le voci .
o ..
. Quindi, è rm -r .
stato un modo efficace per svuotare la directory corrente.
Si noti inoltre che la salvaguardia era solo per un ..
argomento letterale , non per dir/..
o ./..
. Quindi, rm -rf ./.*
rimuoverebbe tutto ricorsivamente nella directory padre.
È interessante vedere che questo era già una soluzione alternativa al bug / malfunzionamento con cui i globs potevano includere .
e ..
nella loro espansione. Ciò è 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 il sh
linguaggio POSIX che richiede l'espansione di .*
includere .
e ..
se vengono restituiti da readdir()
( bash
risolve il problema in parte solo con il punto in shopt -s dotglob
cui i globs (tranne .xxx
quelli) non includono .
o ..
, e con ksh
, puoi risolverlo facendo FIGNORE='@(.|..)'
).
Quando è .
stato aggiunto esattamente anche il divieto , non è sempre chiaro e varia con ogni Unix. Alcuni risultati di seguito.
BSD
La proibizione di è .
stata aggiunta qualche volta tra 2.9BSD (1983) e 2.10BSD (1987) e tra 4.2BSD (1983) e 4.3BSD (1986) (vedere questa modifica con data e ora 1985 nel repository storia unix ).
$ 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/..
, vedere questa modifica nel 1988 (BSD 4.3 Net / 1).
A questa data, il rm
di FreeBSD (e derivati come MacOs) svuota ancora la directory corrente o il genitore al momento rm -rf ./
o rm -rf ../
se (questioni per rm -rf .*/
).
Sistema V
Non ho molte informazioni in quanto né i sorgenti né i file binari sono disponibili pubblicamente per i derivati Unix AT&T dopo V7. Nel suo manuale online, HPUX (basato sul Sistema III) menziona ancora che proibisce solo ..
mentre in effetti proibisce entrambi, il che è un'indicazione che probabilmente almeno SysIII non ha vietato la cancellazione di .
( modifica : Ora guardando il rm
codice sorgente SysIII , è praticamente invariato da Unix V7).
Tutti gli altri manuali online che ho verificato menzionano l'eliminazione .
o ..
è vietato che ci si aspetta che sia conforme a POSIX.
Solaris rm
svuota ancora la directory corrente o parent su rm -rf ./
o rm -rf ../
.
GNU
Il primo log delle modifiche per i file GNU contiene tutte le informazioni storiche.
Sebbene in origine non fossero né cancellate .
né ..
vietate, ..
prima era proibito e poi entrambi (compresi dir/.
), tutti tra il 1990 e il 1991.
altro
Come abbiamo visto, zsh
l'espansione di .*
(o di qualsiasi glob) non include mai .
o ..
(anche in sh
modalità di emulazione). Il rm
builtin (che si ottiene se si zmodload zsh/files
) quindi non tratta .
o ..
appositamente. Quindi, con quel zsh
built-in, puoi rm -rf .
o rm -rf ..
svuotare .
o ..
, ma rm -rf .*
non rimuoverai .
o ..
.
In busybox rm
, il divieto di cancellazione di .
ed è ..
stato aggiunto in 0.52 (2001)
rm
, ma ho pensato che fosse la pena ricordare che si può ancora avere risultati inattesi conchmod
,chown
ecc in caso di corrispondenza.*
.