O rm -rf * removerá todos os arquivos / pastas no diretório atual?


20

Removerá rm -rf *todos os arquivos / pastas no diretório atual? Quero garantir que o curinga *não suba nos diretórios superiores e apague todo o meu sistema de arquivos. : D

Lembro-me de fazer chmod 777 .* -Ra chmodarquivos ocultos e chmoded todo o meu sistema de arquivos. Obviamente, eu estava na conta raiz.


11
É por isso que eu rm -rf ./*especificaria explicitamente o diretório atual ... mas Ankur parece dizer que isso não importa.
— MPEN

@ Mark: qual é a diferença entre .. e ./ ..? Você pode tentar cd ./ .. e ver onde você acabar :)
— Johan

@Johan: Nenhuma diferença ... Eu acho que ele só faz mais sentido na minha cabeça louca: D
— MPEN

@ Marcos: fácil erro fazer :)
— Johan

Respostas:


15

Não, se você não ajustou muito seu shell, isso não removerá arquivos ou diretórios começando com a .. Para removê-los também, você pode listá-los explicitamente

rm -rf .file .dir

ou use os padrões glob certos (obrigado Chris)

rm -rf .[^.]* ..?*

EDIT O ponto aqui é que você não pode usar .*para corresponder arquivos como .file, porque .*ou .*?também corresponderá a ..ou .. .[^.]*corresponde a arquivos como .file, enquanto ..?*corresponde a arquivos como ..foo( *corresponde a zero ou mais caracteres enquanto ?corresponde exatamente a um).


11
Você também precisa de algo como ..?*capturar entradas que começam com ".." (por exemplo ..foo).
— quer

@ Chris: OK, eu comecei esta loucura exigente, você está certo;)
— Benjamin Bannier

não é apenas usar os padrões glob "certos", mas também a quantidade de itens correspondentes. em diretórios com uma grande quantidade de arquivos, o shell provavelmente não é capaz de fornecer 50k arquivos de uma só vez rm. portanto, excluir o conteúdo de um diretório com * não é a maneira mais sábia, imho.
— Akira

Eu acho que explicar xargsestá um pouco além do escopo desta questão. Pode-se, por exemplo, começar a pensar sobre isso quando o shell reclama os comprimentos da lista de argumentos.
— Benjamin Bannier

11
Eu acho que não está fora do escopo, porque eu acho que o OP não tem certeza de como alcançar seu problema / solução final: remova todo o conteúdo do diretório. O OP está fazendo a coisa "errada" geral, já tendo uma solução (ruim) em mente e perguntando por que essa solução causa problemas. Uma abordagem melhor seria: "como excluir todos os arquivos em um diretório sem excluir o próprio diretório?" A solução da OP causará problemas devido à própria natureza de como o globbing funciona.
— Akira

12

Se você deseja remover um diretório e todo o seu conteúdo, pode inseri-lo chdirno diretório pai e no rm -rfdiretório por nome, ignorando toda a pergunta pendente. Se você deseja remover o conteúdo, mas manter o diretório, é mais fácil remover tudo e depois recriar o diretório.

É complexo criar um glob que corresponda a todas as entradas possíveis do diretório, exceto. e ..; é fácil encontrar uma resposta simples (por exemplo, * .??*) que funcione quase sempre na prática. Isso é bom para uso interativo, pois é fácil de lembrar e os horários em que não funciona podem ser detectados com um pós-rm ls -a. Para um script, é mais fácil remover tudo e recriar o diretório vazio.


11
Isso é o que eu gostaria de sugerir também: jogar fora o diretório e feito
— akira

Até tu não é a resposta, é uma boa ideia.
— Johan

10

Como acho que essa pergunta é mais sobre o que * faz (e não rm), vamos tentar outra abordagem.


Se você não tiver certeza do que o * faz, você pode "testar" primeiro usando um comando inofensivo como eco. Antes de executar isso, tente adivinhar o que eles mostrarão se você executá-los no diretório dir.

echo *
echo .*

Mas primeiro vamos criar um playground para que possamos brincar com as estrelas e ver o que acabamos.

mkdir ~/star_test/
cd ~/star_test/
>.file1
>file2

Agora, nesse diretório, temos o seguinte:

cj@zap:~/star_test$ ls -1a
.
..
.file1
file2

Agora observe o que o * expande para usar o comando echo:

cj@zap:~/star_test$ echo *
file2
cj@zap:~/star_test$ echo .*
. .. .file1

Então, vamos ver o que acontece com o comando rm

cj@zap:~/star_test$ rm -rf *
cj@zap:~/star_test$ ls -1a
.
..
.file1

Como você vê, ele removeu apenas o arquivo2, pois * foi expandido apenas para o arquivo2. Se você digitar rm -rf. *, Seria o mesmo que escrever

rm -rf . .. .file1

E para ser honesto, isso não parece divertido;)

Espero que isso esclareça a parte * da sua pergunta.


Atualização: No entanto, como Ankur Goel aponta, existe algum tipo de proteção embutida no rm (algo incomum para comandos do shell :)

Vamos criar um novo playground:

cd ~/star_test/
mkdir -p test1/test2/test3
sudo chown root.root test1
cd test1/test2/test3/
>.file1
>file2

Portanto, agora temos isso de novo, mas com o test1 de propriedade do root como proteção, se o rm começar a enlouquecer.

cj@zap:~/star_test/test1/test2/test3$ ls -a
.  ..  file2  .file1
cj@zap:~/star_test/test1/test2/test3$ echo .*
. .. .file1

Então, vamos remover tudo:

cj@zap:~/star_test/test1/test2/test3$ rm -rf .*
rm: cannot remove directory `.'
rm: cannot remove directory `..'
cj@zap:~/star_test/test1/test2/test3$ ls -a
.  ..  file2

E parece que rm não removeu. e .. mesmo se dissermos para ele !!!

Portanto, após essa longa resposta, é seguro remover tudo em um diretório com isso:

rm -rf * .*

Mas eu usaria isso com cuidado, pois não tenho certeza de que todas as implementações de rm se comportem assim!


7

Sim. O rm -rf excluirá apenas arquivos e pastas no diretório atual e não subirá na árvore de arquivos. O rm também não segue os links simbólicos e exclui os arquivos para os quais eles apontam, para que você não remova acidentalmente outras partes do seu sistema de arquivos.


1

Se você não quiser subir um nível acima como o mpez0 said e rm -rfesta pasta específica, existe uma maneira de trabalhar em todos os diretórios / arquivos, exceto .e ..na pasta atual, fazendo:

rm -rf $(ls -A)

Obviamente, se algum dos diretórios / arquivos contiver um dos caracteres da IFSvariável especial do shell (por exemplo, espaço, guia, nova linha), convém alterar o IFS primeiro, executar o comando e restaurar o IFS.


0

Uma maneira muito mais fácil de esvaziar uma pasta inteira, também evitando os problemas de "muitos argumentos" discutidos nesta resposta , é simplesmente excluir e recriar o próprio diretório. Para garantir que isso funcione corretamente quando você estiver em um diretório com link simbólico, use as seguintes linhas:

cd ..
rm -rf $(readlink -f yourdir) #remove the directory, treat the case of a symlink
                        # by using readlink, to recreate the linked-to directory
mkdir $(readlink -f yourdir) # recreate the directory to have it empty
cd yourdir

(Se você usar em yourdirvez de $(readlink -f yourdir)substituir apenas o link enquanto o local original permanecer cheio)


11
Isso pode interromper as coisas que dependem do inode da pasta e descartar permissões, atime / mtime / ctime / btime, atributos estendidos e listas de controle de acesso.
— Daniel Beck

@DanielBeck obrigado, bons pontos. Embora eu me pergunte, o que validamente valeria o inode além dos hardlinks (nos diretórios, que são fortemente desencorajados de qualquer maneira)? Mas permissões etc são importantes. Assim, na maioria dos casos um general deve provavelmente usar xargs...
— Tobias KIENZLER

O OS X contém um mecanismo que pode lidar com arquivos e pastas movidos e ainda manter a associação. Mais visivelmente no menu Abrir documentos recentes . AFAICT, ele usa inodes para fazer isso internamente. Mais informações . Eu não ficaria surpreso se outros sistemas implementassem algo semelhante, por exemplo, em APIs para programas GUI.
— Daniel Beck
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.