Czy „rm. *” Kiedykolwiek usuwa katalog nadrzędny?


53

Wyrażenie .*jest rozwijane przez bash, aby uwzględnić katalogi bieżący i nadrzędny:

$ ls -la
total 2600
drwxrwxrwx   2 terdon terdon 2162688 Sep 10 16:22 .
drwxr-xr-x 142 terdon terdon  491520 Sep 10 15:34 ..
-rw-r--r--   1 terdon terdon       0 Sep 10 16:22 foo
$ echo .*
. ..

Jeśli uruchomię rm -rf .*na moim Debianie używając GNU bash version 4.2.36(1)-releasei rmod rm (GNU coreutils) 8.13, otrzymam ten komunikat:

$ rm -rf .*
rm: cannot remove directory: `.'
rm: cannot remove directory: `..'

Czy to kwestia GNU, czy POSIX? Czy istnieją systemy * nix, w których powyższe polecenie po cichu usunie .i ..?

Czy jest to również funkcja bezpieczeństwa powłoki lub rmsamego polecenia?


4
Wiem, że to pytanie jest w kontekście rm, ale myślałem, że to warto wspomnieć, że nadal można mieć nieoczekiwane rezultaty chmod, chownitp podczas dopasowywania .*.
Aaron Copley,

Odpowiedzi:


59

Najnowsza (od 2017 r.) Wersja specyfikacji POSIX dla tego rmnarzędzia jest tutaj (i poprzednia tam ) i zabrania usuwania .i ...

Jeśli jeden z plików kropka lub kropka są określone jako część bazowa operandu (to znaczy komponent końcowej nazwy ścieżki) lub jeśli operand jest tłumaczony do katalogu głównego, rm napisze komunikat diagnostyczny do standardowego błędu i nic nie robi więcej z takimi operandami.

Jak zauważył @jlliagre, część o /jest dodatkiem do SUSv4.

Najstarsza publicznie dostępna specyfikacja Uniksa, którą mogłem znaleźć ( XPF4 CAE rev2 (1994)), już ją określiła .i ..nie można jej usunąć, chociaż komentarze w dzienniku zmian plików GNU sugerują, że tak było już w przypadku starszych specyfikacji POSIX.

Należy pamiętać, że dotyczy to dir/..i ../tak dobrze, ale niektóre implementacje UNIX (w tym certyfikowanych tacy jak Solaris 11 i MacOS) nadal nie zabezpieczyć przed rm -rf ../lub rm -rf .*/).

historia

Wczesne jednorożce

-rOpcja rmzostała dodana w Unix V3 (1973), choć to był tylko usuwanie zawartości katalogów, to trzeba jeszcze używać rmdirdo usuwania katalogów.

Zmieniło się to w Unixie V7 (1979, wydaniu, które wprowadziło również powłokę Bourne'a i z którego wywodzi się większość Unices). rm -rteraz również usunął katalogi i nie usunął ..drzewa katalogów. Do strona człowiek stwierdza:

Zabronione jest usuwanie pliku ..tylko w celu uniknięcia aspołecznych konsekwencji niezamierzonego zrobienia czegoś takiego rm -r .*.

(choć można się spierać, że rm -r .*nadal jest aspołeczna, ponieważ usuwa wszystko, ponieważ .jest uwzględniona).

Nadal zgodził się na usunięcie, .chociaż nie rozłączyłby wpisów .ani ... Tak więc, rm -r .jest skutecznym sposobem, aby opróżnić katalog bieżący.

Zauważ też, że zabezpieczenie było tylko dla dosłownego ..argumentu, a nie dla dir/..lub ./... Tak więc rm -rf ./.*nadal rekurencyjnie usuwałbym wszystko z katalogu macierzystego.

Interesujące jest to, że miało to już na celu obejście błędu / nieprawidłowego działania, za pomocą którego globusy mogą obejmować .i ..ich ekspansję. Zostało to naprawione w powłoce Forsyth (podstawa oryginalnej powłoki Minix i pdksh) pod koniec lat 80., zsh(1990) i fish(2005), ale nie w innych powłokach, w szczególności nie w shjęzyku POSIX , który wymaga rozszerzenia o .*włączenie .i ..jeśli są zwracane przez readdir()( bashrozwiązuje problem częściowo tylko wtedy, gdy shopt -s dotglobglobusy (z wyjątkiem .xxxtych) nie zawierają .lub .., i przy pomocy ksh, można to naprawić wykonując FIGNORE='@(.|..)').

Kiedy .również dodano dokładnie zakaz, nie zawsze jest jasne i zmienia się w zależności od Unixa. Kilka ustaleń poniżej.

BSD

Zabronienie .dodano w okresie między 2.9BSD (1983) oraz 2.10BSD (1987) oraz pomiędzy BSD 4.2 (1983) i BSD 4.3 (1986) (patrz w tym zmiana o czasie, w 1985 roku w UNIX-historii repo ).

$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9BSD/root.tar.gz |
    zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `..'
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.10bsd.tar.gz |
    zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `.' or `..'
rm: cannot remove `.' or `..'\n");

Dla dir/.i dir/..zobacz tę zmianę w 1988 r. (BSD 4.3 Netto / 1).

Do tej pory, rmz FreeBSD (i jego pochodne, takie jak MacOS) nadal opróżnia aktualny lub nadrzędnego katalogu na rm -rf ./lub rm -rf ../chociaż (sprawy o rm -rf .*/).

System V.

Nie mam zbyt wielu informacji, ponieważ ani źródło, ani pliki binarne nie są publicznie dostępne dla pochodnych AT&T Unix po V7. W swoim podręczniku online HPUX (oparty na systemie III) wciąż wspomina, że ​​zabrania tylko, ..podczas gdy skutecznie zabrania obu, co oznacza, że ​​prawdopodobnie przynajmniej SysIII nie zabraniał usuwania .( edytuj : Teraz patrząc na kod źródłowy SysIIIrm , jest to praktycznie bez zmian od Unixa V7).

Wszystkie inne podręczniki online, które sprawdziłem, wspominają o usunięciu .lub ..są zabronione, co powinno być zgodne z POSIX.

Solaris rmnadal opróżnia katalog bieżący lub nadrzędny w katalogu rm -rf ./lub rm -rf ../.

GNU ANTYLOPA

Wcześnie changelog dla fileutils GNU posiada wszystkie informacje historyczne.

Chociaż początkowo ani usuwanie .lub ..zostały zakazane, ..było zabronione, a potem oboje (włącznie dir/.), wszystkie w latach 1990 i 1991.

inny

Jak widzieliśmy, zshekspansja .*(lub dowolnego globu) nigdy nie obejmuje .lub ..(nawet w shtrybie emulacji). rmWbudowane (które można uzyskać, jeśli zmodload zsh/files) dlatego nie traktuje .lub ..specjalnie. Tak więc, dzięki temu zshwbudowanemu możesz rm -rf .lub rm -rf ..opróżnić .lub .., ale rm -rf .*nie usuniesz .lub ...

W busybox rmzabroniono usuwania .i ..dodano w 0.52 (2001)


Dziwne, wydaje się, że to precyzuje, że rm -rf . /(zwróć uwagę na spację) należy wydrukować dwa ostrzeżenia (dla .i /) i wyjść, ale wydaje się, że co kilka miesięcy pojawia się pytanie, jak się z tego zregenerować.
Kevin

6
@Kevin Nie wszystkie systemy są zgodne z POSIX, a ograniczenie katalogu głównego zostało tylko jawnie dodane w najnowszej wersji POSIX.
jlliagre

@jlliagre Rozumiem. GNU generalnie próbuje zaimplementować POSIX (oczywiście rozszerzenia +) i wyobrażam sobie, że chcieliby je zainstalować, ale jeśli byłoby to całkiem nowe, to by to wyjaśniało.
Kevin

2
@Stephane: masz rację, ale nadal dodam duże „Tak, to może się zdarzyć! Ale ...” na początku twojej odpowiedzi, aby ludzie bez wątpienia o tym wiedzieli, na niektórych (starszych lub po prostu nie Systemy zgodne z POSIX-em, mogą usuwać katalogi nadrzędne. Zawsze staram się zwracać uwagę na tę możliwość (tzn. Staram się pozostać po bezpiecznej stronie, nawet jeśli czasami utrudnia to czytanie / zapamiętywanie) ^^
Olivier Dulac

1
@ MartinSchröder, Na BSD, został dodany gdzieś pomiędzy 2.8BSD a 2.10BSD (wcześniej zabroniono tylko „..” jak w UnixV7) i pomiędzy 3BSD a 4.3RENO. W systemach SysV jest mniej jasne. Na przykład instrukcja HPUX twierdzi, że zabrania tylko „..”, ale w rzeczywistości zabrania „”. i „..”, to tylko instrukcja jest nieaktualna.
Stéphane Chazelas,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.