Rm -rf * rimuoverà tutti i file / cartelle nella directory corrente?


20

Sarà rm -rf *rimuovere tutti i file / cartelle nella directory corrente? Voglio assicurarmi che il carattere jolly *non si sposti nelle directory superiori e cancelli tutto il mio filesystem. : D

Mi ricordo di aver fatto chmod 777 .* -Rper chmodi file nascosti e chmodEd tutto il mio filesystem. Ovviamente, ero sull'account di root.


1
Ecco perché lo farei rm -rf ./*e specificherei esplicitamente la directory corrente ... ma Ankur sembra dire che non importa comunque.
Aprire il

@Mark: qual è la differenza tra .. e ./ ..? Puoi provare a cd ./ .. e vedere dove finisci :)
Johan

@Johan: Nessuna differenza ... Immagino abbia più senso nella mia testa pazza: D
mpen

@Mark: facile errore da fare :)
Johan

Risposte:


15

No, se non hai ottimizzato molto la shell, questo non rimuoverà i file o le directory che iniziano con a .. Per rimuoverli, puoi anche elencarli esplicitamente

rm -rf .file .dir

o usa i giusti pattern glob (grazie Chris)

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

EDIT Il punto qui è che non è possibile utilizzare .*per abbinare file come .file, perché .*o .*?anche corrispondere ..o .. .[^.]*corrisponde a file simili .file, mentre ..?*corrisponde a file simili ..foo( *corrisponde a zero o più caratteri mentre ?corrisponde esattamente a uno).


1
Hai anche bisogno di qualcosa come ..?*catturare voci che iniziano con “..” (ad es ..foo.).
Chris Johnsen,

@ Chris: OK, ho iniziato questa pazzesca pazzia, hai ragione;)
Benjamin Bannier,

non si tratta solo di utilizzare i modelli glob "giusti", ma anche la quantità di oggetti abbinati. nelle directory con un'enorme quantità di file è molto probabile che la shell non sia in grado di fornire 50k file in un turno rm. quindi, eliminare il contenuto di una directory con * non è il modo più saggio, imho.
Akira,

Penso che spiegare xargssia un po 'oltre lo scopo di questa domanda. Si potrebbe ad esempio iniziare a pensarci quando la shell si lamenta delle lunghezze dell'elenco degli argomenti.
Benjamin Bannier,

1
penso che non sia fuori portata perché penso che OP non sia sicuro di come raggiungere il suo ultimo problema / soluzione: rimuovere tutto il contenuto della directory. OP sta semplicemente facendo la cosa "sbagliata" generale avendo già in mente una soluzione (una cattiva) e chiedendo perché questa soluzione causi problemi. approccio migliore sarebbe: "come eliminare tutti i file in una directory senza eliminare la directory stessa?" La soluzione di OP causerà problemi a causa della natura stessa di come funziona il globbing.
Akira,

12

Se si desidera rimuovere una directory e tutti i suoi contenuti, è possibile chdiraccedere alla directory principale e a rm -rfquella directory per nome, ignorando l'intera domanda sconvolgente. Se si desidera rimuovere il contenuto ma mantenere la directory, è più semplice rimuovere tutto e quindi ricreare la directory.

È complesso trovare un glob che corrisponda a tutte le possibili voci della directory salvate. e ..; è facile trovare una risposta semplice (ad es. * .??*) che funzionerà quasi sempre in pratica. Questo è OK per l'uso interattivo, poiché è facile da ricordare e i tempi in cui non funziona possono essere colti con un post-rm ls -a. Per uno script, è più semplice rimuovere tutto e ricreare la directory vuota.


1
Questo è ciò che suggerirei anche: buttare via la directory e fare
Akira

Anche tu non è la risposta, è una buona idea.
Johan

10

Dal momento che penso che questa domanda riguardi più ciò che * fa (e non rm), proviamo un altro approccio.


Se non sei sicuro di cosa faccia *, puoi prima "testare" usando un comando innocuo come echo. Prima di eseguire questo, prova a indovinare cosa mostreranno se li esegui nella tua home directory.

echo *
echo .*

Ma prima creiamo un parco giochi in modo da poter giocare con le stelle e vedere con cosa finiamo.

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

Ora in questa directory abbiamo questo:

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

Ora nota cosa si espande in * usando il comando echo:

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

Quindi vediamo cosa succede con il comando rm

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

Come vedi, ha rimosso solo il file2, poiché * solo espanso in file2. Se si digita rm -rf. * Sarebbe lo stesso della scrittura

rm -rf . .. .file1

E a dire il vero, non sembra divertente;)

Spero che questo chiarisca la * parte della tua domanda.


Aggiornamento: Comunque, come sottolinea Ankur Goel, c'è un qualche tipo di protezione integrata in rm (un po 'insolito per i comandi della shell :)

Creiamo un nuovo parco giochi:

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

Quindi ora abbiamo di nuovo questo, ma con test1 di proprietà di root come protezione se rm inizia a impazzire.

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

Quindi rimuoviamo tutto:

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 sembra che rm non sia stato rimosso. e .. anche se glielo dicessimo !!!

Quindi, dopo questa lunga risposta, risulta sicuro rimuovere tutto in una directory con questo:

rm -rf * .*

Ma lo userei con cura, poiché non sono sicuro che tutte le implementazioni di rm si comportino in questo modo!


7

Sì. rm -rf eliminerà solo i file e le cartelle nella directory corrente e non salirà nella struttura dei file. Inoltre, rm non seguirà i collegamenti simbolici ed eliminerà i file a cui puntano, quindi non poterai accidentalmente altre parti del tuo filesystem.


1

Se non vuoi alzare di un livello come mpez0 detto e rm -rfquesta cartella specifica, c'è un modo per lavorare su tutte le directory / file tranne .e ..nella cartella corrente facendo:

rm -rf $(ls -A)

Naturalmente, se una qualsiasi delle directory / dei file contiene uno dei caratteri nella IFSvariabile speciale della shell (ad es. Spazio, tab, newline), potresti voler prima cambiare IFS, eseguire il comando, quindi ripristinare IFS.


0

Un modo molto più semplice per svuotare un'intera cartella, evitando anche i problemi "troppi argomenti" discussi in questa risposta , è semplicemente eliminare e ricreare la directory stessa. Per assicurarsi che funzioni correttamente quando ci si trova in una directory con collegamento simbolico, utilizzare le seguenti righe:

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 usi yourdirinvece di $(readlink -f yourdir)sostituire il link solo quando la posizione originale rimane piena)


1
Questo può rompere le cose facendo affidamento sull'inode della cartella e buttare via autorizzazioni, atime / mtime / ctime / btime, attributi estesi ed elenchi di controllo degli accessi.
Daniel Beck

@DanielBeck grazie, buoni punti. Anche se mi chiedo, cosa farebbe affidamento validamente sull'inode oltre agli hardlink (sulle directory, che sono comunque fortemente scoraggiate)? Ma le autorizzazioni ecc. Sono importanti. Quindi nel caso più generale si dovrebbe probabilmente usare xargs...
Tobias Kienzler,

OS X contiene un meccanismo in grado di gestire i file e le cartelle spostati e mantenere comunque l'associazione. Più visibilmente nel menu Apri documenti recenti . AFAICT, usa gli inode per farlo internamente. Maggiori informazioni . Non sarei sorpreso se altri sistemi implementassero qualcosa di simile, ad esempio nelle API per i programmi della GUI.
Daniel Beck
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.