Moje pytanie brzmi: dlaczego -r
podczas tworzenia kopii katalogu wymagane jest użycie flagi (rekurencyjnej)? To znaczy, dlaczego to zrobić:
$ cp -r dir1 copyDir1
Kiedy nie chcę tego zachowania podczas kopiowania katalogu?
Czy rekurencyjna kopia katalogu nie jest tak naprawdę „domyślnym” zachowaniem; zachowanie, którego pragniemy prawie cały czas?
Wygląda na to, że jest to zbędna flaga.
rm
Odpowiedzi:
Jak działają systemy plików, katalog nie jest tak naprawdę folderem zawierającym pliki, ale katalog jest plikiem zawierającym wskaźniki i-węzłów do podłączonych do niego plików „potomnych”. Oznacza to, że z perspektywy systemu plików plik jest plikiem, ale katalog to tylko plik zawierający listę połączonych plików.
Więc z perspektywy wiersza poleceń, robiąc to:
Zasadniczo oznaczałoby to skopiowanie pliku o nazwie
dir1
do nowego pliku o nazwiecopyDir1
. A jeśli chodzi o system plików,dir1
to i tak jest tylko plikiem; fakt, że jest to „katalog”, będzie widoczny tylko wtedy, gdy system plików faktycznie sprawdzi, czy rzeczywiściedir1
jest to stos bitów.-r
Flaga informuje system plików rekursywnie rozwijanego drzewa pliku / katalogu i skopiować całą zawartość i żadnych, które mogą być „dzieckiem” tego pliku do nowego miejsca.Teraz, dlaczego może się to wydawać zbędne lub zbędne, tak naprawdę sprowadza się to do historycznych metod radzenia sobie z systemami plików. Oprócz tworzenia systemu, który jest bezpieczny od wszelkiego rodzaju błędów związanych z użytkownikiem; przypadkowe i celowe.
To znaczy, załóżmy, że masz
~/bin
plik w katalogu domowym, który chcesz skopiować, ale przypadkowo~
pominąłeś - ponieważ jesteś człowiekiem i popełniasz błędy - więc/bin
wygląda to tak:Dzięki „siatce bezpieczeństwa”
/bin
bycia katalogiem w połączeniu z potrzebą-r
flagi unikniesz przypadkowego skopiowania całego binarnego katalogu głównego systemu, w którym jesteś, do katalogu domowego. Gdyby ta siatka bezpieczeństwa nie istniała, nastąpiłaby drobna - lub być może poważna - katastrofa.Logika polega na tym, że w dniach poprzedzających GUI (graficzne interfejsy użytkownika) należy ustawić konwencje logiczne / behawioralne, aby uniknąć tworzenia przez użytkownika wpadek, które potencjalnie mogą zabić system. A używanie
-r
flagi jest teraz jednym z nich.Jeśli wydaje się to zbyteczne, nie musisz szukać dalej niż nowoczesny system GUI, który można umieścić nad systemami plików Linux. GUI rozwiązuje podstawowe problemy użytkownika, takie jak ten, umożliwiając łatwe przeciąganie i upuszczanie plików i katalogów.
Ale w przypadku interfejsów tekstowych wiele „wrażeń użytkownika” w tym świecie to po prostu logiczne i oparte na hueristic guzy drogowe, które pomagają utrzymać kontrolę nad użytkownikiem, aby zapobiec potencjalnej katastrofie.
Podobnie właśnie dlatego systemy plików Linux / Unix nie mają domyślnie ustawionych
777
uprawnień isudo
uprawnień oraz w jaki sposób prawdziwi administratorzy systemu drżą, gdy użytkownik ustawia777
uprawnienia lub przyznaje wszystkimsudo
prawa. Są to podstawowe czynności, które należy wykonać, aby zapewnić stabilność systemu i jak najbardziej „dowód użytkownika”; ktokolwiek spieszy się, by zewrzeć te konwencje, najprawdopodobniej spowoduje uszkodzenie swojego systemu, nawet o tym nie wiedząc.INFORMACJE DODATKOWE: Inna odpowiedź tutaj na stronie Unix Stack Exchange daje dobre wyjaśnienie, dlaczego nierekurencyjna kopia katalogu jest problematyczna; nacisk jest mój.
Jeśli więc katalog jest tak naprawdę plikiem z elementami i-węzłów, wykonanie prostej kopii tego pliku byłoby równoznaczne z działaniem twardego łącza. Którego nie chce.
źródło
cp -r /bin
jakcp-r ~/bin
. Sama flaga nie zapobiega błędom ani niekoniecznie poprawia ostrożność. Jeśli chcesz zapobiec błędom, polecenie cp może równie łatwo spojrzeć na dany węzeł i wyświetlić monit, coś w stylu „To jest katalog, czy chcesz skopiować całą zawartość do określonej lokalizacji (y / n)? ” To byłaby siatka bezpieczeństwa . Wymaganie -r dla katalogów utrzymuje nadmiar kodu w dół bardziej niż cokolwiek innego.To prawda, że takiego zachowania pragniemy prawie cały czas. Nie musi to jednak oznaczać, że kopiowanie rekurencyjne powinno być zachowaniem domyślnym.
Myślę, że przyczyny
cp
działają tak, jak mają swoje korzenie w filozofii Uniksa . Unix faworyzuje programy, które robią jedną rzecz i robią to dobrze , a także programy, które są proste zarówno pod względem interfejsu, jak i implementacji (czasem nazywane gorszym jest lepsze ).Kluczowym elementem łamigłówki jest to, że
cp
nie kopiuje katalogów -cp
kopiuje pliki (i tylko pliki). Jeśli chcesz skopiować katalog,cp
wywołuje się rekurencyjnie , aby skopiować pliki z każdego katalogu.Oczywiście różnica między „kopiowaniem katalogów” a „kopiowaniem plików rekurencyjnie” jest absolutnie niczym, z punktu widzenia użytkownika, ale posiadanie tego interfejsu pomaga zachować prostotę implementacji .
Jeśli
cp
udało Ci się skopiować katalogi, wkrótce pojawi się pokusa, aby dodać więcej funkcji, które mają sens tylko dla katalogów - na przykład możesz chcieć kopiować tylko nazwy plików, które się zakończyły.sh
. Nieuchronnie prowadzi to do rozdęcia i pełzania funkcji , do których jesteśmy przyzwyczajeni w innych systemach operacyjnych - powodując, że oprogramowanie jest powolne, złożone i podatne na błędy.Kolejną zaletą jest to, że
-r
pomaga również użytkownikowi zrozumieć, co naprawdę dzieje się pod interfejsem. Przyjemnym efektem ubocznym jest to, że nauczenie się pojęcia operacji rekurencyjnej zaoszczędzi ci trochę pracy, gdy dowiesz się o innych narzędziach, które ją obsługują (takich jakgrep
na przykład)Niektóre osoby z pewnością powiedzą ci, że ujawnianie szczegółów implementacji użytkownikowi jest złe , a posiadanie większej liczby funkcji jest dobre . Moim celem jest jedynie wyjaśnienie uzasadnienia tego zachowania, więc nie będę się starał kłócić w żaden sposób.
źródło
Interakcje z katalogami zapewniają, że wiesz, że wchodzisz w interakcję z katalogiem, a NIE z pojedynczym plikiem.
Na przykład:
Tak więc, jeśli chcesz pomyślnie skopiować folder, ponieważ oznacza on zarówno folder, jak i obiekty związane z odwoływaniem się do folderu, musisz traktować go jak kolekcję plików:
źródło
Konsekwencją zmiany wartości domyślnej byłoby uszkodzenie tysięcy skryptów powłoki. Prowadzi to do wymagań POSIX i SUS dla dobrze znanego domyślnego zachowania.
Powodem jest historyczny rozwój komend cp, ln i mv (wszystkie te same pliki binarne w większości starych systemów UNIX) w różnych gałęziach UNIX. Kiedy się
-r
pojawił (wcześniecp
nie miał opcji kopiowania katalogów; tutaj jest wczesna strona podręcznika man bez-r
lub-R
), występowały różne różnice w obsłudze specjalnych plików, dowiązań symbolicznych i innych błędów systemu plików.Ze specyfikacji bazowej Open Group Issue 7 :
W rzeczywistości nadal będziesz widzieć niektóre osoby regularnie używające:
Ponieważ nie ufają, że
cp -r
implementacja jest tym, do czego są przyzwyczajeni na dowolnym komputerze; Lub dlatego, że chcą takiegotar
zachowania.źródło
Dzisiaj może to być nieoptymalny interfejs użytkownika, ale decyzja została podjęta około 1970 roku podczas projektowania systemu UNIX, kiedy dysk był znacznie droższy. Miliony skryptów powłoki zależą od tego, czy działa w ten sposób, i jest o wiele za późno, aby to zmienić.
Zobacz ten artykuł, aby uzyskać oryginalne informacje o projekcie.
źródło
Oczywistą zaletą tej
-r
flagi jest to, że możnacp * /target/dir
skopiować tylko wszystkie pliki z katalogu źródłowego do katalogu docelowego, pomijając (choć z ostrzeżeniem) wszystkie zawarte w nim katalogi.cp -r * /target/dir
skopiuje wszystko, łącznie z podkatalogami.źródło
Ta flaga jest potrzebna tylko wtedy, gdy
cp
jest to polecenie do kopiowania plików i katalogów, a nie tylko katalogów.Gdyby istniało specjalne polecenie dla kopii katalogów, zachowanie „domyślne” byłoby z pewnością kopią rekurencyjną.
źródło
mkdir
?Jak wspomnieli inni, katalog to po prostu inny typ pliku (w przeciwieństwie do zwykłego pliku), który zwykle „zawiera” (wskazuje) inne pliki. Może zawierać podkatalogi, których dotyczy to samo ...
Więc jeśli kopiujesz katalog (perspektywa użytkownika), tak naprawdę kopiujesz kilka plików (perspektywa systemu plików) (zwykłe pliki, pliki katalogu, dowiązania symboliczne, ...) i dla każdego pliku katalogu rekurencyjnie to powtarzasz proces. Ponieważ kopiowanie katalogu jest z definicji procesem rekurencyjnym, wywoływany jest argument cp
--recursive
.Oczywiście bardzo łatwo jest utworzyć skrót poleceń w środowisku użytkownika (umieść go w pliku .profile / .bashrc, aby był stale dostępny):
A może lepiej:
W ten sposób możesz skopiować katalog za pomocą
cpa dir1 copyDir1
i nie tylko wydrukuje to, co jest kopiowane, ale także zastosuje uprawnienia do plików.A ponieważ ktoś wspomniał, że CP może teoretycznie wykryć, że plik źródłowy jest katalogiem i zapytać, czy powinien go skopiować rekurencyjnie, oto krótka sugestia:
To tylko tanie opakowanie CP. Zawsze zachowuje wszystkie metadane (tj. Kopiuje czas modyfikacji pliku, poprawnie kopiuje dowiązania symboliczne itd.), A jeśli próbujesz skopiować katalog, pyta, czy powinien go skopiować (rekurencyjnie).
źródło