Dlaczego „cp” i „rm” traktują katalogi osobno?

10

Dlaczego narzędzia lubią katalogi cpi rmtraktują je oddzielnie od zwykłych plików? Oba wymagają, aby użytkownik wyraźnie określił, że chce zachowania rekurencyjnego, w przeciwnym razie w ogóle nie zajmą się katalogami.

Moja pierwsza interakcja (jakiś czas temu) z komputerami odbyła się w środowisku Windows / GUI / wskaż i kliknij / przeciągnij i upuść, zawsze wydawało się naturalne, że te operacje będą zachowywać się tak samo, niezależnie od celu.

To zachowanie szczególnie mnie frustruje, kiedy wydaje polecenia za pomocą symboli wieloznacznych. Co jeśli chcę usunąć wszystko z katalogu ( *) oprócz niepustych podkatalogów ?

Mogę sobie tylko wyobrazić, że jest to jakaś funkcja bezpieczeństwa, która uniemożliwia użytkownikowi zastrzelenie się w stopę, ale jest to sprzeczne z moim rozumieniem kilku zasad uniksowych:

  • Unix zazwyczaj nie chroni użytkownika przed sobą. Zawsze zakładało, że użytkownik wie, co robi.
  • Dla Uniksa wszystko jest plikiem. Czy katalog nie jest tylko kolejnym plikiem? Dlaczego są traktowani inaczej?

Moje pytania:

  • Czy takie zachowanie wynika z ograniczenia technicznego, czy jest to celowy wybór?

A w przypadku tego drugiego

  • czy są jakieś historyczne historie powodów, które uzasadniały ten wybór?
rahmu
źródło
Dla rmprzynajmniej, jeśli chcesz go ignorować różnicę między plików i katalogów, które można umieścić w ~/.bashrcpliku: alias rm='rm -r'.
BenjiWiebe
1
Zobacz także inne, ale powiązane pytanie unix.stackexchange.com/questions/46066/…
derobert
1
Nie można porównać cp i rm z menedżerem plików systemu Windows. Uruchom cmd.exe i spróbuj skopiować, usunąć i porównać zachowanie.
ott--

Odpowiedzi:

11

Dlaczego program uniks mv firmy Derobert nie potrzebuje opcji -R (rekurencyjnej) dla katalogów, ale cp jej potrzebuje? w zasadzie odpowiada na twoje pytanie: kopiowanie lub usuwanie zwykłego pliku różni się od wykonywania tej samej operacji na katalogu, ponieważ dla katalogu musisz przetworzyć wszystkie zawarte w nim pliki. Dlatego operacja jest zasadniczo inna.

Warto również zauważyć, że istnieje specjalne narzędzie, rmdirktóre może działać tylko w pustych katalogach. Bez sprawdzenia faktów prowadzi to do wniosku, że być może pierwotnie rmbył w stanie usunąć tylko katalogi inne niż katalogi, a głębokie usunięcie musiało zostać osiągnięte poprzez rekurencyjne użycie rmdo opróżnienia katalogów, a następnie rmdirich usunięcie.

Peter
źródło
rmdirto także nazwa wywołania systemowego, które zostało użyte do usunięcia katalogu. Katalog musi być pusty dla wywołania systemowego, a narzędzie o tej samej nazwie jest po prostu „front-end”, podobnie jak unlinkpolecenie i narzędzie.
Jordan
Dokładnie - to właśnie prowadzi mnie do przekonania, że ​​pierwotnie rmmogło w ogóle nie być w stanie usunąć katalogów (ponieważ narzędzia wiersza poleceń są często po prostu względnie prostymi opakowaniami wokół wywołań systemowych).
peterph
Tytuł mojego pytania może mylić, że pytam o szczegóły techniczne. Pytałem, czy to celowy wybór. Zastanawiam się, czy tylko ja uważam, że z punktu widzenia użytkownika końcowego takie zachowanie jest niespójne. Przyjmuję twoją odpowiedź, ponieważ pośrednio odpowiada na moje pytanie: ograniczenia techniczne w wewnętrznych systemach uniksowych (na poziomie syscall) wydają się być źródłem tego zachowania, a spuścizna prawdopodobnie uniemożliwia nam zrobienie tego w jakikolwiek inny sposób. Czyż „proste owijanie wokół syscallów” nie powinno dać nam bardziej inteligentnych zachowań?
rahmu
2
Z POV użytkownika końcowego wydaje się to rzeczywiście dziwne, ale w rzeczywistości pytasz o powody. :) Jeśli chodzi o opakowania - wszystko zależy od tego, jak „proste” są (i co nadal chcesz nazwać „prostym”). Modern rmzdecydowanie nie jest zwykłym opakowaniem (potrafi jednocześnie usuwać pliki mroe i katalogi). Jeśli nie podoba ci się -ropcja, użyj funkcji aliasingu swojej powłoki lub stwórz własne opakowanie, które umieści ją na swoim miejscu (co byłoby wolniejsze, ale niezależne od używanej powłoki).
Peter
2

W niektórych wersjach UNIXa strona man rm określa ją jako polecenie rozłączenia pliku.
W systemie UNIX pliki to obiekty w systemie plików o nazwie Inodes, bez nazw i lokalizacji poza identyfikatorem w systemie plików. Ich nazwy są odniesieniami do nich w różnych katalogach, które są rodzajem pliku, który indeksuje pliki (lub katalogi, ponieważ są to pliki), które są w nim wymienione.
Podczas odłączania pliku liczba odwołań do pliku zmniejsza się, a gdy osiągnie wartość 0, jest on faktycznie usuwany, ponieważ jest oznaczony jako wolny przez system plików, a jego bloki / zakresy są również oznaczone jako wolne.

Jeśli masz możliwość zarządzania katalogiem bez uprzedniego odłączenia znajdujących się w nim plików, dojdziesz do punktu, w którym masz i-węzły, do których odwołujesz się w systemie plików, ale nie można uzyskać do niego dostępu w żaden normalny sposób.
Ponieważ istnieje odniesienie do nich zgodnie z ich liczbą odwołań, nie są one oznaczane jako usunięte i stają się utraconymi plikami.
Staje się to jeszcze bardziej skomplikowane, gdy utracone „pliki” są katalogami, i jako takie zwiększają potencjalną ilość utraconej pamięci w systemie plików.

Więc dodano rm -r, jako funkcję ułatwiającą życie użytkownikom UNIX, kosztem standardowego „ducha UNIX”, ponieważ jest bardziej złożony niż klasyczne narzędzia UNIX, ponieważ schodzi do katalogów i usuwa pliki,

Ponadto we wczesnym okresie istnienia systemu UNIX systemy nie miały dużo pamięci, a mapowanie struktury rekurencyjnej katalogu powodowało obniżenie wydajności, a czasem nie można było tego zrobić bez podziału pracy.

cp, czyta plik i kopiuje go, blok po bloku. Gdyby skopiował katalog w taki sam sposób, jak robi plik, dodałby odniesienia do plików w nim bez zwiększania liczby odwołań, co mogłoby prowadzić do niespójności danych (jeśli odczyt / zapis do i-węzła, którego bloki zostały oznaczone jako wolne od czasu ich oryginalny i-węzeł został usunięty), utracono dane - ponieważ usunięcie ostatniego (znanego) odwołania do pliku może spowodować, że jego numer i-węzła zostanie ponownie przetworzony.

Dla tl; dr Crow:
katalogi w UNIX-ie są rodzajem pliku, to prawda, ale ponieważ informacje w nich zawarte są traktowane inaczej przez system, ponieważ są to metadane systemu plików, polecenia manipulujące plikami nie mogą działać w katalogach bez zmienić ich zachowanie, aby manipulować również zależnymi metadanymi.

Didi Kohen
źródło