Desde quando o POSIX e o GNU rm não excluem /?

23

Por vários anos, o rmutilitário GNU não será excluído, a /menos que seja chamado com a --no-preserve-rootopção No entanto, o comando rm -rf /foi apresentado no subconsciente coletivo como perigoso por muito tempo e as pessoas ainda o citam como um comando "assustador".

Eu queria saber quando esta regra que rmnão pode excluir /apareceu pela primeira vez. Eu verifiquei as especificações do POSIX e posso ver que, embora o POSIX: 2008 inclua esse recurso de segurança, o POSIX: 2001 não. Como as versões online das especificações do POSIX são atualizadas de tempos em tempos, a cada novo sub-release, eu também verifiquei a máquina de wayback e encontrei a página relevante do POSIX: 2008 a partir de 2010 e pude confirmar que a regra que rmnão pode ser removida /já estava listado então.

Então, minhas perguntas são:

  • Quando a regra que rmnão pode ser removida foi /adicionada às especificações do POSIX? Foi na edição original de 2008 da Single UNIX Specification versão 4 ou foi adicionada em uma revisão?
  • Quando essa limitação foi adicionada ao GNU rm? Tenho certeza de que foi antes de ser adicionado ao POSIX, mas quando isso aconteceu?
terdon
fonte
2
Consulte também 'rm. *' Já exclui o diretório pai?
Stéphane Chazelas
11
Relacionado: Interpretação do Grupo Austin # 019 (2003), que descreveu (mas não implementou) a alteração.
Michael Homer
4
2003-11-09 git.savannah.gnu.org/gitweb/…
ilkkachu

Respostas:

28

Você pode encontrar a versão HTML de todas as edições do POSIX 2008 online:

Isso foi adicionado na edição de 2008.

As corrigendas técnicas geralmente não adicionam novos recursos.

Você pode ver a versão anterior ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/rm.html ) (POSIX 2004) não tinha esse texto.

O novo texto foi aceito na conferência do grupo austin de 2003-05-09 para inclusão em uma revisão posterior do padrão.

Foi solicitado por John Beck, da Sun Microsystems, em março do mesmo ano (o link requer registro de grupo aberto, consulte também o Pedido de Aprimoramento Número 5 aqui ).

John Beck escreveu, em 11 de março de 2003:

@ page 820 line 31681-31683 section rm comment {JTB-1}

Problem:

Defect code :  3. Clarification required

An occasional user mistake, with devastating consequences, is to
write a shell script with a line such as:
      rm -rf $VARIABLE1/$VARIABLE2
or
      rm -rf /$VARIABLE1
without verifying that either variable is set, which can lead to
      rm -rf /
being the resulting command.  Since there is no plausible
circumstance under which this is the desired behavior, it seems
reasonable to disallow this.  Such a safeguard would, however,
violate the current specification.

Action:

Either extend the exceptions for . and .. on the noted lines
to list / as well, or specify that the behavior of rm if an
operand resolves to / is undefined.

O GNU rmadicionou --preserve-roote --no-preserve-rootopções neste commit de 2003-11-09 , mas --preserve-rootsó se tornou o padrão no commit de 03-09-2006 , portanto no coreutils 6.2

O FreeBSD preserva a barra desde o commit de 04/10/2004 (com um log de commit "Descubra como minhas roupas íntimas são à prova de chamas" ), mas inicialmente não quando estava abaixoPOSIXLY_CORRECT , até que eles se lembraram de verificar uma década depois que o POSIX estava agora obrigando-o a que ponto foi feito também no modo POSIX .

O commit inicial do FreeBSD menciona que o Solaris já estava fazendo naquele momento.

O @JdePB (no comentário abaixo) descobriu que o link para uma matéria privilegiada da Sun corroborava e fornecia mais detalhes sobre a origem do Solaris e sugeria que o Solaris já tinha a salvaguarda em vigor antes de fazer a solicitação ao grupo de Austin.

Explica a justificativa para adicionar essa exclusão. Enquanto um só pode culpar a si mesmo se eles fizerem isso rm -rf /, há um caso em que um script poderia fazê-lo se fazer rm -rf -- "$1/$2"sem verificar que $1/ $2foram fornecidos que é a coisa que atingiu alguns Sun clientes ruim quando aplicar erradamente um patch Solaris (de acordo com esse link).

A proibição de exclusão .e ..foi adicionada muito antes disso e novamente para proteger contra possíveis contratempos. rmainda é um comando perigoso. Ele faz o que deve fazer: remova o que você mandou.

rm -rf /*
cd /tmp &&  rm -rf .*/   # on some systems where rm -rf ../ still removes
                         # the content of ../ and shells that still
                         # may include . and .. in glob expansions.
rm -rf -- "$diretcory"/* # note the misspelled variable name
dir='foo '; rm -rf $dir/*

Também removeria tudo. Sabe-se que a conclusão do nome de arquivo do shell causa esses problemas quando você faz

rm -rf someth<Tab>/*

Expandido para:

rm -rf something /*

Porque somethingassim aconteceu para não ser um diretório.

Os shells gostam tcshou zshadicionam um prompt extra ao tentar chamar rmcom um *curinga ( tcshnão por padrão).

Stéphane Chazelas
fonte
11
Como um jovem SA cooperativo, tentei apagar os arquivos ocultos no diretório de um usuário no SunOS com rm -rf .*seu diretório pessoal. Logo depois, todas as linhas telefônicas se iluminaram ...
Aaron D. Marasco
Aposto $ rm -rf. * = Rm -rf / de uma maneira complicada para chegar lá.
Escoce 14/12/19
@GuruAdrian com certeza, * significa combinar tudo assim. * = .Filename, mas também ../ e, portanto, ../ .. e ../../ .. ad infinatum até você ficar sem espaço de bits para o comando.
Escoce
talvez em conchas modernas. Nem sempre foi assim. Eu deixei essa profundidade de administração e desenvolvimento de sistemas há mais de 15 anos atrás
Escoce