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.