Como evito rm -rf / * acidental?


164

Eu apenas corri rm -rf /*acidentalmente, mas eu quis dizer rm -rf ./*(observe a estrela após a barra).

alias rm='rm -i'e, --preserve-rootpor padrão, não me salvou; existem salvaguardas automáticas para isso?


Eu não era root e cancelei o comando imediatamente, mas havia algumas permissões relaxadas em algum lugar ou algo porque notei que meu prompt do Bash já havia sido quebrado. Não quero depender de permissões e não ser root (eu poderia cometer o mesmo erro sudo), e não quero procurar bugs misteriosos por causa de um arquivo ausente em algum lugar do sistema; portanto, faça backups e sudoseja bom , mas gostaria de algo melhor para este caso específico.


Sobre pensar duas vezes e usar o cérebro. Estou usando na verdade! Mas estou usando-o para resolver algumas tarefas complexas de programação envolvendo 10 coisas diferentes. Estou imerso nesta tarefa profundamente o suficiente, não há poder cerebral sobrando para verificar bandeiras e caminhos, nem sequer penso em termos de comandos e argumentos, penso em termos de ações como 'dir de corrente vazia', uma parte diferente do meu cérebro os traduz em comandos e, às vezes, comete erros. Quero que o computador os corrija, pelo menos os perigosos.


13
Para sua informação, você também pode fazer em rm -rf . /mydirvez de rm -rf ./mydirmatar o diretório em que estava. Acho que isso acontece com mais frequência.
user606723

27
Para usar uma analogia com a arma, esta pergunta diz: por favor, faça com que a arma reconheça que estou apontando para o meu pé e não atirando, mas não quero ter nenhuma responsabilidade por não apontar a arma para o meu pé. Armas e computadores são estúpidos e, se você fizer algo estúpido, obterá esses resultados. Seguindo a analogia da arma, nada impedirá que você se machuque, exceto vigilância e prática.
Slillibri

73
@slillibri Exceto que rmnão é uma arma, é um programa de computador, pode ser inteligente o suficiente para determinar que o usuário excluirá alguns arquivos importantes e emitirá um aviso (como realmente acontece se você tentar ficar rm -rf /sem estrela).
Valentin Nemcev 02/12/19

80
@slillibri As armas têm segurança. Perguntar como colocar segurança melhor no rmcomando é uma pergunta de administrador de sistemas perfeitamente legítima.
Gilles

21
sudo rm / bin / RM não é recomendado, mas irá impedir de mais rm :-)
Paul

Respostas:


220

Um dos truques que sigo é colocar #no começo enquanto estiver usando o rmcomando

root@localhost:~# #rm -rf /

Isso impede a execução acidental rmno arquivo / diretório errado. Depois de verificado, remova #do início. Esse truque funciona, porque no Bash uma palavra que começa com #faz com que essa palavra e todos os caracteres restantes nessa linha sejam ignorados. Portanto, o comando é simplesmente ignorado.

OU

Se você deseja impedir qualquer diretório importante, há mais um truque.

Crie um arquivo nomeado -inesse diretório. Como pode ser criado um arquivo tão estranho? Usando touch -- -ioutouch ./-i

Agora tente rm -rf *:

sachin@sachin-ThinkPad-T420:~$ touch {1..4}
sachin@sachin-ThinkPad-T420:~$ touch -- -i
sachin@sachin-ThinkPad-T420:~$ ls
1  2  3  4  -i
sachin@sachin-ThinkPad-T420:~$ rm -rf *
rm: remove regular empty file `1'? n
rm: remove regular empty file `2'? 

Aqui o *expandirá -ipara a linha de comando, para que seu comando se torne finalmente rm -rf -i. Assim, o comando solicitará antes da remoção. Você pode colocar esse arquivo na sua /, /home/, /etc/, etc.

OU

Use --preserve-rootcomo uma opção para rm. No rmincluído nos coreutilspacotes mais recentes , esta opção é o padrão.

--preserve-root
              do not remove `/' (default)

OU

Use safe-rm

Trecho do site:

O Safe-rm é uma ferramenta de segurança destinada a impedir a exclusão acidental de arquivos importantes, substituindo / bin / rm por um wrapper, que verifica os argumentos fornecidos em uma lista negra configurável de arquivos e diretórios que nunca devem ser removidos.

Os usuários que tentarem excluir um desses arquivos ou diretórios protegidos não poderão fazer isso e receberão uma mensagem de aviso:

$ rm -rf /usr
Skipping /usr

10
safe-rm parece muito bom, olhando para ele agora ...
Valentin Nemcev

45
safe-rm é arrumado. Também é um truque bacana com o -iarquivo. Hah. Festa boba.
EricR

5
Incrível que tipo de truque é feito no unix.
WernerCD

4
O arquivo de criação chamado -i é absolutamente puro gênio. Eu poderia ter usado isso cerca de um ano atrás, quando acidentalmente executei uma rm -rf / etc / * no VPS ... (felizmente, eu tiro instantâneos noturnos, para poder restaurar em menos de 45 minutos).
David W

9
É genial. Sorcery seriatouch -- -rf
Mircea Vutcovici

46

Seu problema:

Acabei de executar rm -rf / * acidentalmente, mas quis dizer rm -rf ./* (observe a estrela após a barra).

A solução: não faça isso! Por uma questão de prática, não use ./no início de um caminho. As barras não agregam valor ao comando e causam apenas confusão.

./*significa a mesma coisa que *, portanto, o comando acima é melhor escrito como:

rm -rf *

Aqui está um problema relacionado. Vejo a expressão a seguir com frequência, em que alguém supõe que FOOestá definido como algo parecido /home/puppies. Eu vi isso hoje, na verdade, na documentação de um grande fornecedor de software.

rm -rf $FOO/

Mas se FOOnão estiver definido, será avaliado como rm -rf /, o que tentará remover todos os arquivos do seu sistema. A barra final é desnecessária, portanto, por uma questão de prática, não a use.

O seguinte fará a mesma coisa e é menos provável que corrompa seu sistema:

rm -rf $FOO

Eu aprendi essas dicas da maneira mais difícil. Quando tive minha primeira conta de superusuário há 14 anos, executei acidentalmente rm -rf $FOO/um script de shell e destruí um sistema. Os outros quatro administradores de sistemas olharam para isso e disseram: 'Sim. Todo mundo faz isso uma vez. Agora, aqui está sua mídia de instalação (36 disquetes). Vá consertar.

Outras pessoas aqui recomendam soluções como --preserve-roote safe-rm. No entanto, essas soluções não estão presentes para todos os variantes Un * xe e podem não funcionar no Solaris, FreeBSD e MacOSX. Além disso, safe-rmrequer a instalação de pacotes adicionais em todos os sistemas Linux que você usa. Se você confiar safe-rm, o que acontece quando você inicia um novo trabalho e ele não está safe-rminstalado? Essas ferramentas são uma muleta e é muito melhor confiar nos padrões conhecidos e melhorar seus hábitos de trabalho.


19
Meu amigo me disse que nunca usa rm -rf *. Ele sempre altera o diretório primeiro e usa um destino específico. O motivo é que ele usa muito o histórico do shell e está preocupado que esse comando possa aparecer na hora errada.
haggai_e

@haggai_e: Boa dica. Quando eu era novo no Unix, eu corri uma vez, encontrei um bug onde rm -rf *também era removido .e ... Eu era root e isso atravessou os diretórios inferiores ../../.., e foi bastante destrutivo. Eu tento ter muito cuidado com isso rm -rf *desde então.
Stefan Lasiewski

2
rm -rf $FOOnão vai ajudar se você precisar rm -rf $FOO/$BAR. cd $FOO && rm -rf $BARvai ajudar, embora seja muito mais longo.
precisa

5
@VictorSergienko, com bash, que tal especificar ${FOO:?}, como em rm -rf ${FOO:?}/e rm -rf ${FOO:?}/${BAR:?}. Isso impedirá que ele se traduza rm -rf /. Tenho mais algumas informações sobre isso na minha resposta aqui .
Acumenos

@haggai_e: Acho que esse é um dos melhores conselhos sobre esse assunto. Eu queimei meu dedo usando rm -rf *um loop for que mudou para o diretório errado por engano e acabou excluindo outra coisa. Se eu tivesse usado um alvo específico, teria uma chance muito menor de excluir a coisa errada.
30515 Richk

30

Como está em "Serverfault", gostaria de dizer o seguinte:

Se você tiver dezenas ou mais servidores, com uma grande equipe de administradores / usuários, alguém está acessando rm -rfou chowno diretório errado.

Você deve ter um plano para recuperar o serviço afetado com o menor MTTR possível.


4
E você deve usar uma VM ou uma caixa de reposição para praticar recuperações - descubra o que não funcionou e refine o plano. Estamos entrando em uma reinicialização quinzenal - porque houve falta de energia em nosso prédio e toda vez que isso foi doloroso. Ao fazer alguns desligamentos planejados de todos os racks, reduzimos o tempo de alguns dias para cerca de 3 horas - cada vez que aprendemos quais bits automatizar / corrigir scripts init.d para etc.
Danny Staple

E tente este comando em uma VM. É interessante! Mas tire um instantâneo primeiro.
Stefan Lasiewski

23

As melhores soluções envolvem mudar seus hábitos para não usar rmdiretamente.

Uma abordagem é executar echo rm -rf /stuff/with/wildcards*primeiro. Verifique se a saída dos curingas parece razoável e use o histórico do shell para executar o comando anterior sem o echo.

Outra abordagem é limitar o echocomando aos casos em que é óbvio o que você excluirá. Em vez de remover todos os arquivos em um diretório, remova o diretório e crie um novo. Um bom método é renomear o diretório existente para DELETE-foo, criar um novo diretório foocom as permissões apropriadas e finalmente removê-lo DELETE-foo. Um benefício colateral desse método é que o comando inserido no seu histórico é rm -rf DELETE-foo.

cd ..
mv somedir DELETE-somedir
mkdir somedir                 # or rsync -dgop DELETE-somedir somedir to preserve permissions
ls DELETE-somedir             # just to make sure we're deleting the right thing
rm -rf DELETE-somedir

Se você realmente insistir em excluir um monte de arquivos porque precisa que o diretório permaneça (porque ele sempre deve existir ou porque você não tem permissão para recriá-lo), mova os arquivos para um diretório diferente e exclua esse diretório .

mkdir ../DELETE_ME
mv * ../DELETE_ME
ls ../DELETE_ME
rm -rf ../DELETE_ME

(Pressione a tecla Alt+ .).

Excluir um diretório de dentro seria atraente, porque rm -rf .é curto, portanto, tem um baixo risco de erros de digitação. Infelizmente, os sistemas típicos não permitem que você faça isso. Você pode, em rm -rf -- "$PWD"vez disso, com um risco maior de erros de digitação, mas a maioria deles leva à remoção de nada. Cuidado que isso deixa um comando perigoso no seu histórico de shell.

Sempre que puder, use o controle de versão. Você não rm, você cvs rmou o que quer, e isso é desfazível.

O Zsh tem opções para avisá-lo antes de executar rmcom um argumento que lista todos os arquivos em um diretório: rm_star_silent(ativado por padrão) solicita antes da execução rm whatever/*e rm_star_wait(desativado por padrão) adiciona um atraso de 10 segundos durante o qual você não pode confirmar. Isso é de uso limitado se você pretende remover todos os arquivos em algum diretório, porque já estará esperando o prompt. Pode ajudar a evitar erros de digitação, como rm foo *para rm foo*.

Existem muitas outras soluções que envolvem a alteração do rmcomando. Uma limitação dessa abordagem é que um dia você estará em uma máquina com o real rme ligará automaticamente rm, seguro na expectativa de uma confirmação ... e em seguida estará restaurando os backups.


mv -t DELETE_ME -- *é um pouco mais infalível.
Tobu

@Giles Não usar rmdiretamente é um bom conselho! Uma alternativa ainda melhor é usar o findcomando .
aculich

E se você precisar que o diretório permaneça, você pode fazer isso simplesmente usando o find somedir -type f -deleteque excluirá todos os arquivos, somedirmas deixará o diretório e todos os subdiretórios.
26512 aculich

19

Você sempre pode fazer um alias, como você mencionou:

what_the_hell_am_i_thinking() {
   echo "Stop." >&2
   echo "Seriously." >&2
   echo "You almost blew up your computer." >&2
   echo 'WHAT WERE YOU THINKING!?!?!' >&2
   echo "Please provide an excuse for yourself below: " 
   read 
   echo "I'm sorry, that's a pathetic excuse. You're fired."
   sleep 2
   telnet nyancat.dakko.us
}

alias rm -fr /*="what_the_hell_am_i_thinking"

Você também pode integrá-lo a um cliente de twitter da linha de comando para alertar seus amigos sobre como você quase se humilhou limpando seu disco rígido rm -fr /*como root.


3
+1 para telnet miku.acm.uiuc.edu
Ali

1
alias echo = "telnet miku.acm.uiuc.edu"
kubanczyk

Não devo ter idade suficiente ... qual é o significado telnet miku.acm.uiuc.edu?
Kyle Strand

Experimente e descubra. É não destrutivo. Se você é tão paranóico quanto deveria, execute em uma VM.
Naftuli Kay

3
-1 Você não pode apelido comandos com espaços entre eles e muito menos / * que é um nome inválido
xenithorb


15

A maneira mais simples de evitar acidentes rm -rf /*é evitar todo o uso do rmcomando! Na verdade, sempre fui tentado a correr rm /bin/rmpara me livrar completamente do comando! Não, eu não estou sendo ridículo.

Em vez disso, use a -deleteopção do findcomando , mas primeiro antes de excluir os arquivos, recomendo visualizar quais arquivos você estará excluindo:

find | less

Observe que, nas versões modernas, findse você deixar de fora o nome de um diretório, ele implicitamente usará o diretório atual; portanto, o acima é o equivalente a:

find . | less

Depois de ter certeza de que esses são os arquivos que você deseja excluir, adicione a -deleteopção:

find path/to/files -delete

Portanto, além de ser find mais seguro de usar, também é mais expressivo ; portanto, se você deseja excluir apenas determinados arquivos em uma hierarquia de diretórios que correspondam a um padrão específico, use uma expressão como essa para visualizar e exclua os arquivos:

find path/to/files -name '*~' | less
find path/to/files -name '*~' -delete

Existem muitas boas razões para aprender e usar, findalém de apenas uma maneira mais segura rm, então você se agradecerá mais tarde se dedicar algum tempo para aprender a usar find.


Discussão muito interessante. Gostei da sua abordagem e fiz um pequeno trecho. É super ineficiente, uma vez que chama encontrar no máximo 3 vezes, mas para mim isso é um bom começo: github.com/der-Daniel/fdel
Daniel Hitzel

14

Há alguns conselhos realmente ruins nesse segmento, felizmente a maioria deles foi rejeitada.

Antes de tudo, quando você precisar ser root, torne-se root - sudo e os vários truques de alias o deixarão fraco. E pior, eles vão te deixar descuidado. Aprenda a fazer as coisas da maneira certa, pare de depender dos pseudônimos para protegê-lo. Um dia, você enraizar-se-á numa caixa que não tem rodinhas e explodirá algo.

Segundo - quando você tiver raízes, pense em si mesmo como dirigindo um ônibus cheio de crianças em idade escolar. Às vezes você pode ouvir a música no rádio, mas outras vezes precisa olhar para os dois lados, desacelerar as coisas e verificar todos os seus espelhos.

Terceiro - Você quase nunca realmente tem que rm -rf- mais provável que você quer mv something something.bakoumkdir _trash && mv something _trash/

Quarto - sempre o lsseu curinga antes rm- Não há nada louco em ver algo antes de destruí-lo para sempre.


2
+1 para uso de ls.
Sachin Divekar

@ eventi Concordo que há alguns conselhos terríveis e hacks feios neste tópico. E é definitivamente uma boa idéia de olhar para alguma coisa antes de destruí-lo, mas há uma maneira ainda melhor de fazer isso usando o findcomando .
aculich

Não vejo como encontrar é mais simples ou seguro, mas gosto do seu find . -name '*~'exemplo. O que lsquero dizer é que listará a mesma glob que rmserá usada.
28812

11

Esse é o meu padrão especificamente para regexps no contexto de rm, mas teria salvado você nesse caso.

Eu sempre faço echo foo*/[0-9]*{bar,baz}*primeiro, para ver o que o regexp vai corresponder. Depois de obter a saída, volto com a edição da linha de comando e mudo echopara rm -rf. Eu nunca, nunca uso rm -rfem uma regexp não testada .



5
OK, o que estou procurando? Você está argumentando que a sintaxe regexp para a correspondência de arquivos é diferente (e às vezes chamada por um nome diferente) daquela usada em, por exemplo, perl? Ou algum outro ponto que eu perdi? Peço desculpas pela minha lentidão de pensamento, é a primeira coisa que acontece aqui na manhã de sábado!
MadHatter

9
Essas coisas que você está chamando de "regexp" são de fato globs. Não é uma sintaxe diferente de regex; não é uma regex.
bukzor

1
Esse argumento certamente poderia ser feito; no entanto, no artigo da wikipedia sobre expressões regulares, considero que "Muitos sistemas de computação modernos fornecem caracteres curinga nos nomes de arquivos correspondentes de um sistema de arquivos. Esse é um recurso essencial de muitos shells da linha de comando e também é conhecido como globbing" - observe o o uso de "também conhecido como", o que me parece indicar que os tokens de chamada que contêm metacaracteres para corresponder a um ou mais nomes de arquivo regexps não estão errados. Concordo que globbing é um termo melhor porque não significa nada além do uso de expressões regulares na correspondência de nome de arquivo.
MadHatter

1
@ MadHatter Além disso, o globbing, embora visualmente um pouco semelhante, é muito diferente semanticamente das expressões regulares. Em uma regex, o significado de *tem uma definição muito precisa chamada Kleene Star, que é um operador unário que corresponde a zero ou mais elementos do conjunto ao qual é aplicado (no caso de expressões regulares, o caractere ou conjunto de caracteres que precede o Kleene Star), enquanto, ao observar as *correspondências, qualquer coisa no padrão a seguir. Eles são semanticamente muito diferentes, mesmo que pareçam ter uma sintaxe semelhante.
aculich

9

A solução para esse problema é fazer backups regulares. Sempre que você produz algo que não quer arriscar perder, faça o backup. Se você achar que fazer backup regularmente é muito doloroso, simplifique o processo para que não seja doloroso.

Por exemplo, se você trabalha com código-fonte, use uma ferramenta semelhante gita espelhar o código e manter o histórico em outra máquina. Se você trabalha com documentos, tenha um script que seja rsyncseus documentos para outra máquina.


Um sistema de arquivos copy-on-write, como o btrfs, também pode ajudar. Você pode configurar facilmente uma rotação de instantâneo automatizada simples que é executada localmente (além do backup externo).
Malthe

6

Parece que a melhor maneira de reduzir esse risco é ter uma exclusão em dois estágios, como a maioria das GUIs. Ou seja, substitua rm por algo que move as coisas para um diretório da lixeira (no mesmo volume). Em seguida, limpe o lixo após um tempo suficiente para perceber qualquer erro.

Um desses utilitários, trash-cli, é discutido no Unix StackExchange, aqui .


É a primeira coisa que instalo em todas as máquinas. Deve ser a ferramenta de remoção padrão, com o rm sendo usado apenas quando você precisa remover absolutamente alguma coisa no momento. Fico triste por ainda não ter decolado, mas um dia o fará. Provavelmente após uma instância muito pública de rm, causando um enorme problema que não poderia ter sido solucionado por backups. Provavelmente algo em que o tempo necessário para se recuperar desempenha um fator enorme.
Gerry

Depois de usar o linux por 20 anos, ainda acho que deve haver algum tipo de comportamento de lixeira rm.
Shovas 7/03/18

3

Um fator importante para evitar esse tipo de erro é não fazer login usando a conta root. Quando você efetua login usando o usuário não privilegiado normal, você precisa usar sudopara cada comando. Então, você deve ter mais cuidado.


4
Não estou convencido de que o sudo impediria algo assim. Você pode digitar o mesmo erro que o OP, mesmo se digitar "sudo" antes de "rm".
Cjc

1
Trabalhando mencionado como root em editar
Valentin Nemcev

Se você ainda não está convencido sobre o uso sudoe os backups. Dê uma olhada nesta página: forum.synology.com/wiki/index.php/… . Ele fala sobre a criação de uma lixeira. Espero que isto ajude!
Khaled

1
@Khaled Estou usando sudo e backups, eu só quero algo melhor para este problema específico
Valentin Nemcev

3

Quando excluo um diretório recursivamente, coloco o -r, e -fse aplicável, no final do comando, por exemplo rm /foo/bar -rf. Dessa forma, se eu acidentalmente pressionar Enter muito cedo, sem ter digitado o caminho inteiro ainda, o comando não será recursivo, portanto é provavelmente inofensivo. Se eu pressionar Enter ao tentar digitar a barra depois /foo, escrevi em rm /foovez de rm -rf /foo.

Isso funciona muito bem em sistemas que usam os GNU coreutils, mas os utilitários em alguns outros Unixes não permitem que opções sejam colocadas no final dessa maneira. Felizmente, não uso esses sistemas com muita frequência.


2

Pode ser complicado, mas você pode configurar funções no SELinux para que, mesmo que o usuário se torne root via sudo su - (ou su simples), a capacidade de excluir arquivos possa ser limitada (você deve fazer login diretamente como root para remover arquivos). Se você estiver usando o AppArmor, poderá fazer algo semelhante .

Obviamente, a outra solução seria garantir que você tenha backups. :)


2

Evite usar globbing . No Bash, você pode definir noglob. Mas, novamente, quando você muda para um sistema onde noglobnão está definido, você pode esquecer isso e continuar como se estivesse.

Defina noclobberpara impedir mve cpdestruir arquivos também.

Use um navegador de arquivos para exclusão. Alguns navegadores de arquivos oferecem uma lixeira (por exemplo, Konqueror ).

Outra maneira de evitar o globbing é a seguinte. Na linha de comando, eu echo filenamepattern >> xxx. Em seguida, edito o arquivo com o Vim ou vi para verificar quais arquivos devem ser excluídos (observe os caracteres padrão do nome do arquivo nos nomes de arquivos.) E depois uso %s/^/rm -f/para transformar cada linha em um comando de exclusão. Fonte xxx. Dessa forma, você vê todos os arquivos que serão excluídos antes de fazê-lo.

Mova os arquivos para um diretório ou sótão 'sótão'. Ou use o controle de versão (como dito antes de mim).


+1 para usar algum método de pré-visualização de seus arquivos antes de excluí-los, no entanto, existem maneiras mais simples e mais seguros para fazer isso usando o findcomando .
26612 aculich


1

Fora chattrisso, não há muitas salvaguardas de permitir que o root execute esse comando. É por isso que grupos adequados e comandos cuidadosos são importantes ao executar privilégios.

Próxima vez; escopo dos arquivos que você planeja excluir - omita 'f' de rm -rfou use finde passe-o paraxargs rm


É bom que você sugira o uso find, mas recomendo uma maneira mais segura de usá-lo na minha resposta . Não há necessidade de usar, xargs rmpois todas as versões modernas do findtêm a -deleteopção . Além disso, para usar com segurança, xargs rmvocê também precisará usá find -print0- xargs -0 rmlo; caso contrário, terá problemas ao encontrar coisas como nomes de arquivos com espaços.
Aculich

Meu ponto não era sobre as nuances sobre xargs mas sim usando encontrar em primeiro lugar, sem a exclusão de arquivos e, em seguida, continuar ..
thinice

Sim, acho que o escopo de arquivos usando findé uma boa sugestão; no entanto, as nuances de xargssão importantes se você sugerir usá-lo; caso contrário, isso gera confusão e frustração ao encontrar arquivos com espaços (o que é evitado usando a -deleteopção).
aculich

1

Alguns aliases de segurança para outros comandos, para evitar desastres semelhantes, encontrados aqui :

# safety features
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -I'                    # 'rm -i' prompts for every file
alias ln='ln -i'
alias chown='chown --preserve-root'
alias chmod='chmod --preserve-root'
alias chgrp='chgrp --preserve-root'

Observe que as maiúsculas -Isão diferentes de -i:

uma vez antes de remover mais de três arquivos ou ao remover recursivamente. Menos invasivo que -i, enquanto ainda protege contra a maioria dos erros


Embora a opção I não retorne o que você excluirá.
Calmarius

1

Normalmente, uso o -vsinalizador para ver o que está sendo excluído e tenho a chance de ^Crapidamente, se tiver a menor dúvida. Não é realmente uma maneira de evitar maus rm's, mas isso pode ser útil para limitar o dano no caso de algo correr mal.


1

Meu processo de exclusão em máquinas baseadas em Unix é o seguinte.

  • Digite ls /path/to/intented/file_or_directoryna janela do terminal e pressione return(ou Tab, conforme desejado), para ver a lista de arquivos.

Se tudo parece bom,

  • clique na up arrowtecla para recuperar ls /path/to/intented/file_or_directoryo histórico do terminal.

  • substitua lspor rmou rm -rou rm -rf, conforme necessário. Eu, pessoalmente, não gosto de usar -fbandeira.

Esse processo de validação também impede a execução prematura do rmcomando, algo que aconteceu comigo, antes de começar a seguir esse processo.


Visualizar os arquivos primeiro antes de excluí-los é uma boa idéia, e existe uma maneira ainda mais segura e expressiva de fazê-lo usando o find que explico na minha resposta .
26412 aculich

1

Se você não está com disposição para adquirir novos hábitos agora, .bashrc/.profileé um bom lugar para adicionar alguns testes para verificar se você está prestes a fazer algo estúpido. Eu imaginei que em uma função Bash eu poderia receber um padrão que poderia arruinar o meu dia e surgiu com isso:

alias rm='set -f; myrm' #set -f turns off wildcard expansion need to do it outside of           
                        #the function so that we get the "raw" string.
myrm() {
    ARGV="$*"
    set +f #opposite of set -f
    if echo "$ARGV" | grep -e '-rf /*' \
                           -e 'another scary pattern'
    then
        echo "Do Not Operate Heavy Machinery while under the influence of this medication"
        return 1
    else
        /bin/rm $@
    fi
}

O bom disso é que é apenas o Bash.

Claramente, não é genérico o suficiente nesse formulário, mas acho que tem potencial, por isso, poste algumas idéias ou comentários.


É bom que você esteja tentando visualizar seus arquivos antes de excluí-los, mas essa solução é muito complicada. Em vez disso você pode fazer isso de maneira muito simples de uma forma mais genérica usando o findcomando . Além disso, não entendo por que você diz "o bom disso é que é apenas o Bash"? É recomendável evitar bash-isms em scripts .
26612 aculich

Para nos impedir de "rm -rf / *" ou "rm -rf dir / *" quando queremos dizer "rm -rf ./*" e "rm -rf dir / *", precisamos detectar os padrões "/ *" e "*" (simplista). Mas não podemos simplesmente passar todos os argumentos da linha de comando pelo grep procurando algum padrão prejudicial, porque o bash expande os argumentos curinga antes de transmiti-los (a estrela será expandida para todo o conteúdo de uma pasta). Precisamos da sequência de caracteres "bruta". Isso é feito com set -f antes de chamarmos a função "myrm", que passa então pela sequência de argumentos bruta e o grep procura padrões predefinidos. *
kln

Entendo o que você está tentando fazer com o set -fque é equivalente set -o noglobno Bash, mas isso ainda não explica sua afirmação de que "o lado bom disso é que é apenas o Bash". Em vez disso você pode eliminar totalmente o problema e de uma forma genérica para qualquer shell por não usar rmem tudo, mas sim usando o findcomando . Você já tentou essa sugestão para ver como ela se compara ao que você sugere aqui?
aculich

@aculich por apenas bash Quero dizer sem dependências python ou perl, tudo pode ser feito no bash. Depois de alterar meu .bashrc, posso continuar trabalhando sem ter que quebrar velhos hábitos. Toda vez que invoco o rm bash, me certifico de que não faço algo estúpido. Eu apenas tenho que definir alguns padrões dos quais quero ser alertado. Como "*", que removeria tudo da pasta atual. De vez em quando, será exatamente o que eu quero, mas com um pouco mais de trabalho, a interatividade pode ser adicionada ao "myrm".
kln

@aculich OK, entendi.Não, eu não tentei.Eu acho que exige uma mudança significativa no fluxo de trabalho. Acabei de verificar aqui no Mac OS X meu .bash_history é 500 e 27 desses comandos são rm. E hoje em dia eu não uso um terminal com muita frequência.
kln

1

Infelizmente, não posso deixar um comentário acima devido ao carma insuficiente, mas queria alertar outras pessoas de que a empresa segura não é uma panacéia para pesadelos acidentais com exclusão em massa.

O seguinte foi testado em uma máquina virtual Linux Mint 17.1 (aviso para aqueles que não estão familiarizados com esses comandos: Na verdade, até mesmo aqueles que estão familiarizados com esses comandos nunca deveriam / provavelmente nunca faria isso para evitar perda de dados catastrófica):

Versão em texto (condensada):

$ cd /
$ sudo safe-rm -rf *
$ ls
bash: /bin/ls: No such file or directory

Versão da imagem (completa):

insira a descrição da imagem aqui


1

Eu gosto da abordagem das janelas da lixeira.

Normalmente, crio um diretório chamado "/ tmp / recyclebin" para tudo o que preciso excluir:

mkdir /tmp/recyclebin

E nunca use rm -rf, eu sempre uso:

mv target_folder /tmp/recyclebin

Depois, esvazio a lixeira usando um script manualmente ou manualmente.


0

Hehe (não testado e um tanto ridículo!):

$ cat /usr/local/bin/saferm

#! /bin/bash

/bin/ls -- "$@"

echo "Those be the files you're about to delete."
echo "Do you want to proceed (y/N)?"

read userresponse

if [ "$userresponse" -eq "y" ]; then

  echo "Executing...."
  /bin/rm -- "$@"

fi

E depois:

alias rm="/usr/local/bin/saferm"

Realisticamente, você deve fazer uma pausa mental antes de executar esse tipo de operação com um glob, esteja executando como root, acrescentando "sudo" a ele etc. Você pode executar um "ls" no mesmo glob etc. mas, mentalmente, você deve parar por um segundo, verifique se digitou o que queria, verifique se o que deseja é realmente o que deseja etc. Suponho que isso é algo que é aprendido principalmente pela destruição de algo no primeiro ano como Unix SA, da mesma maneira que o queimador de calor é um bom professor, dizendo que algo no fogão pode estar quente.

E verifique se você tem bons backups!


Eu tento pensar duas vezes antes de fazer coisas perigosas, mas de alguma forma nem sempre funciona, eu destruí as coisas no passado por causa de desatenção como essa.
Valentin Nemcev 02/12/19

0

Além disso, não como uma salvaguarda, mas como uma maneira de descobrir quais arquivos foram excluídos antes de clicar em ^ C, você pode usar o locatebanco de dados (é claro, apenas se ele tiver sido instalado e sobreviver rm)

Eu aprendi sobre isso nesta postagem do blog


0

Basta usar o ZFS para armazenar os arquivos necessários para resistir à remoção acidental e ter um daemon que:

  • regularmente faz instantâneos deste sistema de arquivos
  • remove instantâneos antigos / desnecessários.

Se os arquivos forem removidos, sobrescritos, corrompidos, o que for, basta reverter seu sistema de arquivos para um clone do último bom instantâneo e pronto.


0

não tanto uma resposta, mas uma dica, eu sempre rm (dir) -rfnão faço, rm -rf (dir)ou seja: não se torne nuclear até o último momento possível.

Isso ajuda a atenuar as situações nas quais você digita o nome do diretório de maneira que ainda seja uma exclusão válida, como deslizar e pressionar a tecla Enter.


Inteligente, mas não funcionaria no BSD rm, onde as opções devem vir antes dos nomes dos arquivos.
Svenper

sim. Eu descobri isso usando a Apple recentemente. A correção é instalar as ferramentas gnu e definir aliases para tudo :) e / ou preferencialmente jogar a maçã em uma lata de lixo. :)
Sirex


1
se me fosse permitido, em um nanossegundo. É lixo comparado ao linux.
precisa

0

Eu acho que essa é uma dica de prevenção poderosa, com * atalho de expansão no shell:

Primeiro, digite rm -rf *ou rm -rf your/path/*, NÃO digite a Enterchave. (é claro, você deve ter o hábito de se preocupar em não pressionar Enter rápido / acidentalmente ao usar rm -rf)

Em seguida, pressione Alt-Shift-8(ou seja Alt-Shift-*) para expandir o curinga "*" explicitamente no bash. Isso também evita inserir novamente um comando "rm -rf *" ao navegar pelo histórico.

Finalmente, depois de marcada, a expansão possui os arquivos / diretórios corretos, pressione Enter.

Feito.


0

Caso isso ajude alguém lá fora, para o seu próprio caso:

1. Use rmsafe:

Ele move os arquivos para uma pasta "lixeira" e você sempre tem a chance de trazê-los de volta com um simples mv:

$ rmsafe /path/to/important/files

Fonte: https://github.com/pendashteh/rmsafe

2. Use safe:

Você pode definir um alias para rmusar safe:

$ alias rm="safe rm"

Agora, se você executar, rm /*obtém isso em resposta:

$ rm /*
Are you sure you want to 'rm /bin /boot /data /dev /etc /home /initrd.img /lib /lib64 /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var'? [y/n]

e acredito que você não digitará y!

Fonte: https://github.com/pendashteh/safe

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.