A versão mais recente (a partir de 2017) da especificação POSIX para o rmutilitário está aqui (e a anterior lá ) e proíbe a exclusão de .e ...
Se um dos arquivos ponto ou ponto estiver especificado como a parte do nome de base de um operando (ou seja, o componente final do nome do caminho) ou se um operando for resolvido para o diretório raiz, a rm escreverá uma mensagem de diagnóstico para erro padrão e não fará nada mais com esses operandos.
Conforme observado por @jlliagre, a parte sobre /é uma adição ao SUSv4.
A mais antiga especificação do Unix disponível publicamente que eu pude encontrar ( XPF4 CAE rev2 (1994)), já especificou isso .e ..não pode ser removida, embora comentários no changelog do arquivo GNU sugeram que esse já era o caso nas especificações POSIX mais antigas.
Note-se que ela se aplica a dir/..e ../bem, mas algumas implementações (incluindo aqueles UNIX certificadas como Solaris 11 e MacOS) ainda não salvaguarda contra rm -rf ../ou rm -rf .*/).
história
Unices iniciais
A -ropção para rmfoi adicionada no Unix V3 (1973), embora excluindo apenas o conteúdo dos diretórios, você ainda precisará usar rmdirpara remover os diretórios.
Isso mudou no Unix V7 (1979, o lançamento que também introduziu o shell Bourne e do qual a maioria dos Unices deriva). rm -ragora removeu os diretórios também e não excluiu a ..árvore de diretórios. A página do manual declara:
É proibido remover o arquivo ..apenas para evitar as conseqüências anti-sociais de se fazer algo assim inadvertidamente rm -r .*.
(embora se possa argumentar que rm -r .*ainda é anti - social , pois exclui tudo porque .está incluído).
Ele ainda aceitou remover, .mas não desvinculou as entradas .ou ... Então, rm -r .era uma maneira eficaz de esvaziar o diretório atual.
Observe também que a salvaguarda era apenas para um ..argumento literal , não para dir/..ou ./... Portanto, rm -rf ./.*ainda removeria tudo no diretório pai recursivamente.
É interessante ver que isso já era para contornar o bug / falha de recurso pelo qual os globs poderiam incluir .e ..em sua expansão. Isso foi corrigido no shell Forsyth (a base do shell Minix original e do pdksh) no final dos anos 80, zsh(1990) e fish(2005), mas não em outros shells e, em particular, não na shlinguagem POSIX que requer a expansão de .*incluir .e ..se eles são retornados por readdir()( bashaborda o problema parcialmente apenas com shopt -s dotglobonde globs (exceto .xxxos) não incluem .ou .., e com ksh, você pode corrigi-lo fazendo isso FIGNORE='@(.|..)').
Quando exatamente proibir .também foi adicionado nem sempre é claro e varia de acordo com cada Unix. Algumas descobertas abaixo.
BSDs
A proibição de .foi adicionada em algum momento entre 2.9BSD (1983) e 2.10BSD (1987) e entre 4.2BSD (1983) e 4.3BSD (1986) (veja essa alteração com timestamp 1985 em 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");
Para dir/.e dir/..veja esta alteração em 1988 (BSD 4.3 Net / 1).
Até essa data, o rmFreeBSD (e derivados como o macOS) ainda esvazia o diretório atual ou pai sobre rm -rf ./ou rm -rf ../embora (é importante rm -rf .*/).
Sistema V
Não tenho muita informação, pois nem a fonte nem o binário estão disponíveis publicamente para os derivados da AT&T Unix após a V7. Em seu manual online, HPUX (com base no Sistema III) ainda menciona que apenas proíbe ..enquanto efetivamente proíbe tanto que é uma indicação de que, provavelmente, pelo menos SysIII não proibiu a exclusão de .( edição : Agora, olhando para o SysIII rmcódigo-fonte , é praticamente inalterado desde o Unix V7).
Todos os outros manuais on-line que verifiquei mencionam a exclusão .ou ..são proibidos, o que é esperado que seja compatível com POSIX.
O Solaris rmainda esvazia o diretório atual ou pai em rm -rf ./ou rm -rf ../.
GNU
O registro de alterações antecipado dos arquivos do GNU possui todas as informações históricas.
Embora originalmente não excluísse .ou ..fosse proibido, ..era proibido primeiro e depois ambos (inclusive dir/.), todos entre 1990 e 1991.
de outros
Como vimos, em zsh, a expansão de .*(ou qualquer glob) nunca inclui .ou ..(mesmo no shmodo de emulação). O rmbuiltin (que você obtém se você zmodload zsh/files), portanto, não trata .ou ..especialmente. Portanto, com esse zshbuiltin, você pode rm -rf .ou rm -rf ..esvaziar .ou .., mas rm -rf .*não removerá .ou ...
No busybox rm, a proibição de exclusão .e ..foi adicionada em 0,52 (2001)
rm, mas achei que valia a pena mencionar que você ainda pode ter resultados inesperados comchmod,chown, etc quando a correspondência.*.