Czy rm -rf * usunie wszystkie pliki / foldery z bieżącego katalogu?

20

Czy rm -rf *usunie wszystkie pliki / foldery w bieżącym katalogu? Chcę się upewnić, że symbol wieloznaczny *nie przesunie się w wyższych katalogach i nie usunie całego mojego systemu plików. :RE

Pamiętam robi chmod 777 .* -Rdo chmodukrytych plików i chmoded cały mój system plików. Oczywiście byłem na koncie roota.

Olivier Lalonde
źródło
1
Właśnie dlatego zrobiłbym rm -rf ./*i wyraźnie określiłem bieżący katalog ... ale Ankur wydaje się mówić, że to i tak nie ma znaczenia.
mpen
@ Mark: jaka jest różnica między .. a ./ ..? Możesz spróbować cd ./ .. i zobaczyć, gdzie skończysz :)
Johan
@Johan: Bez różnicy ... Wydaje mi się, że to ma więcej sensu w mojej szalonej głowie: D
mpen
@ Mark: łatwa pomyłka do zrobienia :)
Johan

Odpowiedzi:

15

Nie, jeśli nie poprawiłeś dużo swojej powłoki, nie usunie to plików ani katalogów zaczynających się od .. Aby je również usunąć, możesz albo podać je jawnie

rm -rf .file .dir

lub użyj odpowiednich globalnych wzorców (dzięki Chris)

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

EDYCJA Chodzi o to, że nie można użyć .*do dopasowania plików takich jak .file, ponieważ .*lub .*?będzie również pasować ..lub .. .[^.]*dopasowuje pliki jak .file, a ..?*dopasowuje pliki jak ..foo( *dopasowuje zero lub więcej znaków, a ?dopasowuje dokładnie jeden).

Benjamin Bannier
źródło
1
Potrzebujesz także czegoś takiego, jak ..?*przechwytywanie wpisów zaczynających się na „..” (np ..foo.)
Chris Johnsen
@Chris: OK, zacząłem to wybredne szaleństwo, masz rację;)
Benjamin Bannier
nie chodzi tylko o użycie „właściwych” wzorów globów, ale także o liczbę dopasowanych przedmiotów. w katalogach z dużą ilością plików powłoka najprawdopodobniej nie jest w stanie podać 50 000 plików za jednym razem rm. więc usunięcie zawartości katalogu z * nie jest najmądrzejszym sposobem, imho.
akira,
Myślę, że wyjaśnienie xargsjest nieco poza zakresem tego pytania. Można np. Zacząć o tym myśleć, gdy powłoka skarży się na długość listy argumentów.
Benjamin Bannier
1
myślę, że to nie jest poza zakresem, ponieważ myślę, że OP nie jest pewny, jak osiągnąć swój ostateczny problem / rozwiązanie: usunąć całą zawartość katalogu. OP po prostu robi ogólną „złą” rzecz, mając już na myśli rozwiązanie (złe) i pyta, dlaczego to rozwiązanie powoduje problemy. lepszym rozwiązaniem byłoby: „jak usunąć wszystkie pliki w katalogu bez usuwania samego katalogu?” Rozwiązanie OP spowoduje problemy ze względu na sam charakter działania globowania.
akira,
12

Jeśli chcesz usunąć katalog i całą jego zawartość, możesz przejść do katalogu chdirnadrzędnego i do rm -rftego katalogu według nazwy, omijając całe pytanie globbing. Jeśli chcesz usunąć zawartość, ale zachować katalog, najłatwiej jest usunąć wszystko, a następnie ponownie utworzyć katalog.

Opracowanie globu, który pasuje do wszystkich możliwych zapisów w katalogu, jest skomplikowane. i ..; łatwo jest znaleźć prostą odpowiedź (np. * .??*), która zadziała prawie zawsze w praktyce. Jest to OK do użytku interaktywnego, ponieważ jest łatwe do zapamiętania, a czasy, kiedy nie działa, można złapać za pomocą post-rm ls -a. W przypadku skryptu łatwiej jest usunąć wszystko i odtworzyć pusty katalog.

mpez0
źródło
1
To również sugerowałbym: wyrzuć katalog i gotowe
akira
Nawet jeśli to nie jest odpowiedź, to dobry pomysł.
Johan
10

Ponieważ myślę, że to pytanie dotyczy bardziej tego, co * robi (a nie rm), spróbujmy innego podejścia.


Jeśli nie masz pewności, co robi *, możesz najpierw „przetestować”, używając nieszkodliwego polecenia, takiego jak echo. Zanim to uruchomisz, spróbuj zgadnąć, co pokażą, jeśli uruchomisz je w swoim domu, reż.

echo *
echo .*

Ale najpierw stwórzmy plac zabaw, abyśmy mogli bawić się z gwiazdami i zobaczyć, z czym skończymy.

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

Teraz w tym katalogu mamy to:

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

Teraz zwróć uwagę na to, co * rozwija się za pomocą polecenia echo:

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

Zobaczmy więc, co dzieje się z poleceniem rm

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

Jak widzisz, usunął tylko plik2, ponieważ * rozwinął się tylko do pliku2. Jeśli wpiszesz rm -rf. *, To będzie to samo co pisanie

rm -rf . .. .file1

I szczerze mówiąc, to nie wygląda zabawnie;)

Mam nadzieję, że to wyjaśnia * część twojego pytania.


Aktualizacja: Jednak, jak zauważa Ankur Goel, w rm jest wbudowana ochrona (coś niezwykłego dla poleceń powłoki :)

Stwórzmy nowy plac zabaw:

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

Teraz mamy to ponownie, ale z test1 będącym własnością roota jako ochrona, jeśli rm zacznie szaleć.

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

Więc usuńmy wszystko:

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

I wygląda na to, że rm nie usunął. i .. nawet gdybyśmy mu kazali !!!

Po tej długiej odpowiedzi okazuje się, że można bezpiecznie usunąć wszystko w reż z tym:

rm -rf * .*

Ale użyłbym tego ostrożnie, ponieważ nie jestem pewien, czy wszystkie implementacje rm zachowują się w ten sposób!

Johan
źródło
7

Tak. rm -rf usunie tylko pliki i foldery w bieżącym katalogu i nie wejdzie na drzewo plików. rm nie będzie także podążał za dowiązaniami symbolicznymi i nie usuwał wskazywanych przez siebie plików, aby przypadkowo nie przyciąć innych części systemu plików.

Ankur Goel
źródło
1

Jeśli nie chcesz przechodzić o jeden poziom wyżej, jak mpez0 powiedział i rm -rften konkretny folder, istnieje sposób pracy na wszystkich katalogach / plikach z wyjątkiem .iw ..bieżącym folderze poprzez:

rm -rf $(ls -A)

Oczywiście, jeśli którykolwiek z katalogów / plików zawiera jeden ze znaków w IFSspecjalnej zmiennej powłoki (np. Spacja, tabulator, nowa linia), możesz najpierw zmienić IFS, uruchomić polecenie, a następnie przywrócić IFS.

tzot
źródło
0

Znacznie łatwiejszym sposobem na opróżnienie całego folderu, unikając również problemów „zbyt wielu argumentów” omawianych w tej odpowiedzi , jest po prostu usunięcie i ponowne utworzenie samego katalogu. Aby upewnić się, że działa to poprawnie, gdy znajdujesz się w katalogu z dowiązaniem symbolicznym, użyj następujących wierszy:

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

(Jeśli użyjesz yourdirzamiast tego $(readlink -f yourdir), zamienisz link tylko wtedy, gdy pierwotna lokalizacja pozostanie pełna)

Tobias Kienzler
źródło
1
Może to zepsuć elementy zależne od i-węzła folderu i zrzucić uprawnienia, atime / mtime / ctime / btime, rozszerzone atrybuty i listy kontroli dostępu.
Daniel Beck
@DanielBeck dzięki, dobre punkty. Chociaż zastanawiam się, na czym właściwie polegałby i-węzeł oprócz hardlinków (na katalogach, które i tak są mocno odradzane)? Ale uprawnienia itp. Są ważne. Więc w najbardziej ogólnym przypadku należy prawdopodobnie użyć xargs...
Tobias Kienzler
OS X zawiera mechanizm, który może obsługiwać przenoszone pliki i foldery i nadal zachowywać powiązanie. Najbardziej widoczne w menu Otwórz ostatnie dokumenty . AFAICT, używa wewnętrznych i-węzłów. Więcej informacji . Nie zdziwiłbym się, gdyby inne systemy zaimplementowały coś podobnego np. W interfejsach API dla programów GUI.
Daniel Beck