Dlaczego `cp` został zaprojektowany do dyskretnego nadpisywania istniejących plików? [Zamknięte]

30

Testowałem cpza pomocą następujących poleceń:

$ ls
first.html   second.html  third.html

$ cat first.html
first

$ cat second.html
second

$ cat third.html
third

Następnie kopiuję first.htmldo second.html:

$ cp first.html second.html

$ cat second.html
first

Plik second.htmljest dyskretnie nadpisywany bez żadnych błędów. Jeśli jednak zrobię to w graficznym graficznym interfejsie użytkownika, przeciągając i upuszczając plik o tej samej nazwie, zostanie on dodany first1.htmlautomatycznie. Pozwala to uniknąć przypadkowego zastąpienia istniejącego pliku.

Dlaczego cpzamiast tego po cichu nadpisywać pliki?

Algebra
źródło
10
Wyobrażam sobie, że tylko projektanci Coreutils mogą naprawdę odpowiedzieć na to pytanie, ale tak właśnie działa. Zwykle aplikacje są budowane przy założeniu, że użytkownik naprawdę oznacza, co robią, i aby zminimalizować dodatkowe podpowiedzi. Jeśli chcesz zmienić zachowanie, alias „cp” na „cp -i” lub „cp -n”.
kevlinux
8
@kevlinux Twórcy coreutils właśnie wdrażają standard POSIX.
Kusalananda
17
Ponieważ w czasach, gdy był projektowany, ludzie chcieli być tak zwięzli, jak to tylko możliwe, dzięki temu, co robią (stąd nie kopiują cp) i wiedzieli, co zrobili, a kiedy popełniali błędy, nie próbowali obwiniać narzędzi. Wtedy to zupełnie inny rodzaj ludzi zajmował się komputerami. To tak, jakby pytać, dlaczego skalpel dla chirurga serca może również przeciąć ręce.
PlasmaHH
4
Unix został zaprojektowany przez ekspertów komputerowych i dla nich, przy założeniu, że użytkownik wiedział, co robi. System operacyjny zrobiłby dokładnie to, co powiedział mu użytkownik, jeśli to możliwe - bez trzymania go za rękę i bez proszenia o niekończące się potwierdzenia. Jeśli operacja coś nadpisała, przyjęto, że tego właśnie chciał użytkownik. Pamiętaj też, że to był początek lat siedemdziesiątych - przed MS DOS, Windows i komputerami domowymi - prowadzenie i trzymanie ręki użytkownika na każdym kroku nie było jeszcze powszechne. Ponadto, gdy teletype jest przetwarzany jako terminale, proszenie o potwierdzenie zawsze byłoby zbyt kłopotliwe.
Baard Kopperud
10
NIE alias cpdo cp -ilub podobny, ponieważ będziesz przyzwyczaić do posiadania siatki bezpieczeństwa, systemy, w których nie jest dostępne co (większość z nich), które znacznie bardziej ryzykowne. Lepiej nauczyć się rutynowo cp -iitp., Jeśli tak wolisz.
Reid

Odpowiedzi:

52

Domyślne zachowanie nadpisywania cpjest określone w POSIX.

  1. Jeśli plik_źródłowy jest typu zwykłego pliku, należy podjąć następujące kroki:

    3.a. Zachowanie jest nieokreślone, jeśli plik_doc istnieje i został zapisany w poprzednim kroku. W przeciwnym razie, jeśli plik_doc istnieje, należy podjąć następujące kroki:

    3.ai Jeśli opcja -i jest aktywna, narzędzie cp wypisze monit o błędzie standardowym i odczyta wiersz ze standardowego wejścia. Jeśli odpowiedź nie jest twierdząca, cp nie zrobi nic więcej z plikiem_źródłowym i przejdzie do pozostałych plików.

    3.a.ii. Deskryptor pliku dla dest_file należy uzyskać, wykonując akcje równoważne funkcji open () zdefiniowanej w woluminie interfejsów systemowych POSIX.1-2017, wywoływanej przy użyciu argumentu dest_file jako argumentu ścieżki oraz zawierającej bit bitów OR z O_WRONLY i O_TRUNC jako argument oflag.

    3.a.iii. Jeśli próba uzyskania deskryptora pliku nie powiedzie się i obowiązuje opcja -f, cp spróbuje usunąć plik, wykonując akcje równoważne z funkcją unlink () zdefiniowaną w wolumenie interfejsów systemowych POSIX.1-2017, wywoływaną za pomocą pliku_ dest jako argument ścieżki. Jeśli próba się powiedzie, CP kontynuuje krok 3b.

Kiedy pisano specyfikację POSIX, istniała już duża liczba skryptów, z wbudowanym założeniem domyślnego zachowania nadpisywania. Wiele z tych skryptów zaprojektowano do działania bez bezpośredniej obecności użytkownika, np. Jako zadania cron lub inne zadania w tle. Zmiana zachowania złamałaby je. Przejrzenie i zmodyfikowanie ich wszystkich w celu dodania opcji wymuszania nadpisywania wszędzie tam, gdzie było to potrzebne, zostało prawdopodobnie uznane za ogromne zadanie przy minimalnych korzyściach.

Ponadto linia poleceń systemu Unix zawsze była zaprojektowana tak, aby umożliwić doświadczonemu użytkownikowi wydajną pracę, nawet kosztem ciężkiej krzywej uczenia się dla początkującego. Kiedy użytkownik wprowadza polecenie, komputer oczekuje, że użytkownik naprawdę to rozumie, bez żadnego odgadywania; obowiązkiem użytkownika jest ostrożność w przypadku potencjalnie niszczących poleceń.

Kiedy opracowano oryginalny Unix, systemy miały tak mało pamięci i pamięci masowej w porównaniu do współczesnych komputerów, że zastępują ostrzeżenia i monity prawdopodobnie były postrzegane jako marnotrawstwo i niepotrzebne luksusy.

Kiedy pisano standard POSIX, precedens został mocno ustalony, a autorzy standardu doskonale zdawali sobie sprawę z zalet niezniszczenia kompatybilności wstecznej .

Poza tym, jak opisali inni, każdy użytkownik może dodawać / włączać te funkcje dla siebie, używając aliasów powłoki lub nawet budując cppolecenie zastępowania i modyfikując je, $PATHaby znaleźć zamiennik przed standardowym poleceniem systemowym, i uzyskać w ten sposób siatkę bezpieczeństwa, jeśli pożądany.

Ale jeśli to zrobisz, przekonasz się, że stwarzasz zagrożenie dla siebie. Jeśli cppolecenie zachowuje się w jeden sposób, gdy jest używane interaktywnie, a w inny sposób, gdy jest wywoływane ze skryptu, możesz nie pamiętać, że istnieje różnica. W innym systemie możesz być nieostrożny, ponieważ przyzwyczaiłeś się do ostrzeżeń i podpowiedzi w swoim własnym systemie.

Jeśli zachowanie w skryptach nadal będzie zgodne ze standardem POSIX, prawdopodobnie przyzwyczaisz się do podpowiedzi w trybie interaktywnym, a następnie napiszesz skrypt, który wykonuje masowe kopiowanie - i wtedy znowu zauważysz, że coś przypadkowo nadpisałeś.

Jeśli wymuszasz także wyświetlanie monitów w skryptach, co zrobi polecenie, gdy uruchomisz je w kontekście, w którym nie ma użytkownika, np. Procesy w tle lub zadania cron? Czy skrypt zawiesza się, przerywa lub zastępuje?

Wieszanie lub przerywanie oznacza, że ​​zadanie, które miało zostać wykonane automatycznie, nie zostanie wykonane. Brak nadpisania może czasami powodować sam problem: na przykład może spowodować, że stare dane zostaną przetworzone dwukrotnie przez inny system, zamiast zostać zastąpione aktualnymi danymi.

Duża część mocy wiersza poleceń wynika z faktu, że gdy już wiesz, jak coś zrobić w wierszu polecenia, domyślnie wiesz również, jak to zrobić automatycznie przez skrypt . Jest to jednak prawdą tylko wtedy, gdy polecenia, których używasz interaktywnie, działają dokładnie tak samo, gdy są wywoływane w kontekście skryptu. Wszelkie znaczące różnice w zachowaniu między użyciem interaktywnym a użyciem skryptowym stworzą rodzaj dysonansu poznawczego, który jest denerwujący dla zaawansowanego użytkownika.

telcoM
źródło
54
„Dlaczego tak to działa?” „Ponieważ standard tak mówi”. „Dlaczego standard tak mówi?” „Ponieważ już to działało, podobało mi się to”.
Baptiste Candellier
16
Ostatni akapit jest prawdziwym powodem. Okna dialogowe potwierdzenia i
pytania
@BaptisteCandellier - Uzgodniony. Jest tak, jakby ostateczny powód był tam, ale kusząco tuż poza zasięgiem tej odpowiedzi.
TED
2
Ten ostatni akapit mówi, dlaczego rm -rfjest tak skuteczny, nawet jeśli tak naprawdę nie chciałeś uruchomić go w swoim katalogu domowym ...
Max Vernon
2
@ TED Zabawne, że nikt nigdy nie wspomina, jak syscall unlink (2) również „nie” prosi „Matko, czy mogę?” O potwierdzenie, ilekroć te półprzyjemne dyskusje znów odwracają się od nich. :)
tchrist
20

cppochodzi z początku Uniksa. Było to na długo przed napisaniem standardu Posix. Rzeczywiście: Posix właśnie sformalizował istniejące zachowanie cpw tym zakresie.

Rozmawiamy wokół Epoki (1970-01-01), kiedy mężczyźni byli prawdziwymi mężczyznami, kobiety były prawdziwymi kobietami i futrzastymi małymi stworzeniami ... (dygresję). W tych czasach dodanie dodatkowego kodu spowodowało, że program stał się większy. To był wtedy problem, ponieważ pierwszym komputerem z systemem Unix był PDP-7 (z możliwością aktualizacji do 144 KB pamięci RAM!). Więc rzeczy były małe, wydajne, bez zabezpieczeń.

Tak więc w tamtych czasach musieliście wiedzieć, co robicie, ponieważ komputer po prostu nie był w stanie powstrzymać cię przed zrobieniem czegoś, czego później żałowałeś.

(Jest ładny rysunek Zevara; wyszukaj „zevar cerveaux assiste par ordinateur”, aby znaleźć ewolucję komputera. Lub spróbuj http://perinet.blogspirit.com/archive/2012/02/12/zevar-et- cointe.html tak długo, jak istnieje

Dla naprawdę zainteresowanych (widziałem spekulacje w komentarzach): Oryginał cpna pierwszym Uniksie zawierał około dwóch stron kodu asemblera (C przyszedł później). Odpowiednią częścią było:

sys open; name1: 0; 0   " Open the input file
spa
  jmp error         " File open error
lac o17         " Why load 15 (017) into AC?
sys creat; name2: 0     " Create the output file
spa
  jmp error         " File create error

(Więc trudny sys creat)

I, gdy już to jesteśmy: używana wersja 2 Uniksa (fragment kodu)

mode = buf[2] & 037;
if((fnew = creat(argv[2],mode)) < 0){
    stat(argv[2], buf);

co jest również trudne creatbez testów i zabezpieczeń. Zauważ, że kod C dla V2 Unix cpto mniej niż 55 linii!

Ljm Dullaart
źródło
5
Prawie słusznie, z wyjątkiem tego, że to „ małe futrzaste ” (stworzenia z Alpha Centauri), a nie „ małe futrzaste ”!
TripeHound
1
@TED: Jest całkowicie możliwe, że wczesne wersje cpwłaśnie edytowanego openmiejsca docelowego O_CREAT | O_TRUNCwykonały pętlę read/ write; pewnie, z nowoczesnym cpjest tyle pokręteł, że w zasadzie musi statnajpierw spróbować dotrzeć do miejsca docelowego, i może najpierw łatwo sprawdzić istnienie (i robi to z cp -i/ cp -n), ale jeśli oczekiwania zostałyby ustalone na podstawie oryginalnych cpnarzędzi bez kości , zmieniając to zachowanie niepotrzebnie łamałby istniejące skrypty. To nie jest tak, jak nowoczesne powłoki, z aliasktórych nie można po prostu ustawić cp -idomyślnie interaktywnego użycia.
ShadowRanger
@ShadowRanger - Hmmm. Masz całkowitą rację, że tak naprawdę nie mam pojęcia, czy było to łatwe, czy trudne. Komentarz usunięty.
TED
1
@ShadowRanger Tak, ale to popycha ciężką lekcję w dół, dopóki nie pojawi się system produkcyjny ...
Chrylis -on strike-
1
@sourcejedi: Fun! Nie zmienia to mojej podstawowej teorii (że łatwiej było po prostu bezwarunkowo otworzyć za pomocą skrótu i creatzdarza się, że jest to odpowiednik open+ O_CREAT | O_TRUNC), ale brak O_EXCLwyjaśnia, dlaczego nie byłoby tak łatwo obsługiwać istniejące pliki; próba zrobienia tego byłaby z natury ryzykowna (w zasadzie musiałbyś open/ statsprawdzić istnienie, a następnie użyć creat, ale na dużych współużytkowanych systemach zawsze jest to możliwe, zanim dotrzesz creat, ktoś utworzył plik, a teraz wysadziłeś i tak dalej). Również może nadpisać bezwarunkowo.
ShadowRanger
19

Ponieważ te polecenia są również przeznaczone do użycia w skryptach, być może uruchamianych bez jakiegokolwiek nadzoru ze strony człowieka, a także dlatego, że istnieje wiele przypadków, w których naprawdę chcesz zastąpić cel (filozofia powłok Linuxa polega na tym, że człowiek wie, co ona robi)

Istnieje jeszcze kilka zabezpieczeń:

  • GNU cpma -n| --no-clobberopcja
  • jeśli skopiujesz kilka plików do jednego cp, narzekasz, że ostatni nie jest katalogiem.
ksenoid
źródło
Dotyczy to tylko implementacji specyficznej dla dostawcy, a pytanie nie dotyczyło implementacji specyficznej dla dostawcy.
schily
10

Czy to „robić jedną rzecz na raz”?

Ten komentarz brzmi jak pytanie o ogólną zasadę projektowania. Często pytania na ten temat są bardzo subiektywne i nie jesteśmy w stanie napisać właściwej odpowiedzi. Ostrzegamy, że w tej sprawie możemy zamknąć pytania.

Czasami mamy wyjaśnienie oryginalnego wyboru projektu, ponieważ deweloperzy napisali o nich. Ale nie mam tak ładnej odpowiedzi na to pytanie.

Dlaczego cpjest tak zaprojektowany?

Problem w tym, że Unix ma ponad 40 lat.

Jeśli tworzysz teraz nowy system, możesz dokonać różnych wyborów projektowych. Ale zmiana Uniksa złamałaby istniejące skrypty, jak wspomniano w innych odpowiedziach.

Dlaczego został cp zaprojektowany do dyskretnego nadpisywania istniejących plików?

Krótka odpowiedź brzmi „nie wiem” :-).

Zrozum, że cpto tylko jeden problem. Myślę, że żaden z oryginalnych programów poleceń nie był chroniony przed nadpisywaniem lub usuwaniem plików. Powłoka ma podobny problem podczas przekierowywania danych wyjściowych:

$ cat first.html > second.html

To polecenie również po cichu zastępuje second.html.

Interesuje mnie, w jaki sposób można przeprojektować wszystkie te programy. Może to wymagać dodatkowej złożoności.

Myślę, że jest to część wyjaśnienia: wczesny Unix podkreślał proste implementacje . Aby uzyskać bardziej szczegółowe wyjaśnienie, patrz „gorsze jest lepsze”, połączone na końcu tej odpowiedzi.

Możesz zmienić, > second.htmlaby zatrzymał się z błędem, jeśli second.htmljuż istnieje. Jednak, jak już wspomnieliśmy, czasami użytkownik nie chce, aby zastąpić istniejący plik. Na przykład może budować złożone polecenie, próbując kilka razy, aż zrobi to, co chce.

Użytkownik może uruchomić rm second.htmlnajpierw, jeśli zajdzie taka potrzeba. To może być dobry kompromis! Ma kilka własnych wad.

  1. Użytkownik musi wpisać nazwę pliku dwa razy.
  2. Ludzie mają też wiele problemów z używaniem rm. Więc chciałbym też uczynić rmbezpieczniejszym. Ale jak? Jeśli rmpokażemy każdą nazwę pliku i poprosimy użytkownika o potwierdzenie, musi ona teraz napisać trzy wiersze poleceń zamiast jednego. Ponadto, jeśli będzie musiała to robić zbyt często, przyzwyczai się i wpisze „y”, aby potwierdzić bez zastanowienia. Może to być bardzo denerwujące i nadal niebezpieczne.

W nowoczesnym systemie zalecam zainstalowanie trashpolecenia i używanie go zamiast, gdy to rmmożliwe. Wprowadzenie pamięci Trash było świetnym pomysłem np. Dla graficznego komputera dla jednego użytkownika .

Myślę, że ważne jest również zrozumienie ograniczeń oryginalnego sprzętu uniksowego - ograniczona pamięć RAM i miejsce na dysku, wydajność wyświetlana na wolnych drukarkach, a także oprogramowanie systemowe i programistyczne.

Zauważ, że oryginalny Uniks nie miał uzupełniania tabulatorami , aby szybko wypełnić nazwę pliku dla rmpolecenia. (Również oryginalna powłoka Bourne'a nie ma historii poleceń, np. Kiedy używasz klawisza strzałki w górę bash).

Przy wyjściu drukarki, należy użyć edytora linii opartej ed. Jest to trudniejsze do nauczenia niż wizualny edytor tekstu. Musisz wydrukować kilka bieżących wierszy, zdecydować, w jaki sposób chcesz je zmienić i wpisać polecenie edycji.

Użycie > second.htmljest trochę jak użycie polecenia w edytorze linii. Efekt, jaki ma, zależy od bieżącego stanu. (Jeśli second.htmljuż istnieje, jego zawartość zostanie odrzucona). Jeśli użytkownik nie jest pewien aktualnego stanu, oczekuje się, że uruchomi się lslub ls second.htmlpierwszy.

„Proste wdrożenie” jako zasada projektowania

Istnieje popularna interpretacja projektu Uniksa, która zaczyna się:

Projekt musi być prosty, zarówno pod względem implementacji, jak i interfejsu. Ważniejsze jest, aby implementacja była prosta niż interfejs. Prostota jest najważniejszym czynnikiem przy projektowaniu.

...

Gabriel argumentował, że „Gorzej jest lepiej” produkuje bardziej udane oprogramowanie niż podejście MIT: tak długo, jak początkowy program jest zasadniczo dobry, jego wdrożenie zajmie znacznie mniej czasu i wysiłku i łatwiej będzie dostosować się do nowych sytuacji. Na przykład przenoszenie oprogramowania na nowe maszyny staje się znacznie łatwiejsze. W ten sposób jego użycie rozprzestrzeni się szybko, na długo zanim [lepszy] program będzie miał szansę zostać opracowany i wdrożony (przewaga pierwszego gracza).

https://en.wikipedia.org/wiki/Worse_is_better

sourcejedi
źródło
Dlaczego nadpisywanie celu cp„problemem”? Interaktywne proszenie o pozwolenie lub niepowodzenie może być równie dużym „problemem” jak to.
Kusalananda
wow, dziękuję uzupełnij wytyczną: 1) Napisz programy, które robią jedną rzecz i robią to dobrze. 2) Zaufaj programatorowi.
Algebra
2
Utrata danych @Kusalananda stanowi problem. Osobiście jestem zainteresowany zmniejszeniem ryzyka utraty danych. Istnieją różne podejścia do tego. Powiedzenie, że jest to problem, nie oznacza, że ​​alternatywy również nie mają problemów.
sourcejedi
1
@riderdragon Programy napisane w języku C mogą często zawieść w bardzo zaskakujący sposób, ponieważ C ufa programistom. Ale programiści nie są tak niezawodni. Musimy pisać bardzo zaawansowane narzędzia, takie jak valgrind , które są potrzebne, aby znaleźć błędy popełniane przez programistów. Myślę, że ważne jest, aby mieć języki programowania takie jak Rust, Python lub C #, które próbują egzekwować „bezpieczeństwo pamięci” bez zaufania programistom. (Język C został stworzony przez jednego z autorów UNIX-a, aby napisać UNIX-a w przenośnym języku).
sourcejedi
1
Jeszcze lepiej cat first.html second.html > first.htmlda wynik first.htmlnadpisania second.htmltylko zawartością . Oryginalna zawartość zostaje utracona na zawsze.
doneal24,
9

Projekt „cp” sięga pierwotnego projektu Uniksa. Istotnie, istniała spójna filozofia stojąca za projektem Uniksa, która była nieco mniej niż w połowie żartobliwie określana jako Worse-is-Better * .

Podstawową ideą jest to, że uproszczenie kodu jest tak naprawdę ważniejszym zagadnieniem projektowym niż posiadanie idealnego interfejsu lub „robienie właściwej rzeczy”.

  • Prostota - projekt musi być prosty, zarówno pod względem implementacji, jak i interfejsu. Ważniejsze jest, aby implementacja była prosta niż interfejs . Prostota jest najważniejszym czynnikiem przy projektowaniu.

  • Prawidłowość - projekt musi być poprawny we wszystkich możliwych do zaobserwowania aspektach. Nieco lepiej jest być prostszym niż poprawnym.

  • Spójność - konstrukcja nie może być nadmiernie niespójna. W niektórych przypadkach spójność można poświęcić dla uproszczenia, ale lepiej jest porzucić te części projektu, które dotyczą mniej powszechnych okoliczności, niż wprowadzić złożoność implementacyjną lub niespójność.

  • Kompletność - projekt musi obejmować tyle ważnych sytuacji, ile jest praktycznych. Należy uwzględnić wszystkie uzasadnione spodziewane przypadki. Kompletność można poświęcić na rzecz jakiejkolwiek innej jakości. W rzeczywistości należy poświęcić kompletność za każdym razem, gdy zagrożona jest prostota implementacji. Aby zachować kompletność, można zachować konsekwencję, jeśli zachowana zostanie prostota; szczególnie bezwartościowa jest spójność interfejsu.

( moje podkreślenie )

Pamiętając, że to był 1970 rok, użyłem „Chcę skopiować ten plik tylko wtedy, gdy jeszcze nie istnieje” byłby dość rzadkim przypadkiem użycia przez osobę wykonującą kopię. Jeśli tego właśnie chciałeś, będziesz w stanie sprawdzić przed kopią, a to może nawet zostać skrypty.

Co do tego, dlaczego system operacyjny z takim podejściem projektowym okazał się tym, który zwyciężył nad wszystkimi innymi systemami operacyjnymi budowanymi w tym czasie, autor eseju również miał na to teorię.

Kolejną korzyścią wynikającą z filozofii „gorsze jest lepsze” jest to, że programista jest uwarunkowany, aby poświęcić trochę bezpieczeństwa, wygody i kłopotów, aby uzyskać dobrą wydajność i niewielkie wykorzystanie zasobów. Programy napisane przy użyciu metody New Jersey będą działać dobrze zarówno na małych, jak i dużych komputerach, a kod będzie przenośny, ponieważ jest napisany na wirusie.

Należy pamiętać, że początkowy wirus musi być w zasadzie dobry. Jeśli tak, rozprzestrzenianie się wirusa jest zapewnione, o ile jest przenośne. Gdy wirus się rozprzestrzeni, pojawi się presja, aby go ulepszyć, być może poprzez zwiększenie jego funkcjonalności bliżej 90%, ale użytkownicy są już uwarunkowani, aby zaakceptować gorsze niż właściwe. Dlatego najpierw gorsze jest lepsze oprogramowanie, po pierwsze, zyska akceptację, po drugie uzależni swoich użytkowników od mniejszych oczekiwań, a po trzecie poprawi się do punktu, który jest prawie właściwy.

* - lub to, co autor, ale nikt inny, nie nazwał „podejściem z New Jersey” .

PRZETRZĄSAĆ
źródło
1
To właściwa odpowiedź.
tchrist
+1, ale myślę, że lepiej byłoby mieć konkretny przykład. Kiedy instalujesz nową wersję programu, który edytowałeś i ponownie skompilowałeś (a może przetestowałeś :-), celowo chcesz zastąpić starą wersję programu. (I prawdopodobnie chcesz podobne zachowanie z Twojego kompilator. Tak wcześnie UNIX ma tylko creat()vs open(). open()Nie może utworzyć plik, jeśli nie istnieje. To trwa tylko 0/1/2 dla odczytu / zapisu / oba. To nie jest jeszcze podjąć O_CREAT, i nie ma O_EXCL).
sourcejedi
@sourcejedi - Przepraszam, ale jako programista sam nie mogę wymyślić innego scenariusza niż ten, w którym robiłbym kopię. :-)
TED,
@TED ​​przepraszam, to znaczy sugeruję ten przykład, jako jeden z nierzadkich przypadków, w których zdecydowanie chcesz zastąpić, w porównaniu do porównania w pytaniu, w którym być może nie.
sourcejedi
0

Głównym powodem jest to, że GUI jest z definicji interaktywne, podczas gdy plik binarny /bin/cpjest po prostu programem, który można wywoływać z różnych miejsc, na przykład z GUI ;-). Założę się, że nawet dziś większość połączeń do /bin/cpnie będzie z prawdziwego terminala z użytkownikiem wpisującym polecenie powłoki, ale raczej z serwera HTTP, systemu pocztowego lub NAS. Wbudowana ochrona przed błędami użytkownika ma sens w interaktywnym środowisku; mniej w prostym pliku binarnym. Na przykład, GUI najprawdopodobniej zadzwoni /bin/cpw tle, aby wykonać rzeczywiste operacje i będzie musiał poradzić sobie z pytaniami dotyczącymi bezpieczeństwa w standardzie, nawet jeśli tylko zapytał użytkownika!

Zauważ, że od pierwszego dnia było prawie banalnie napisać bezpieczne opakowanie, /bin/cpjeśli jest to pożądane. Filozofią * nix jest zapewnienie użytkownikom prostych elementów składowych: z nich /bin/cpjest jeden.

Peter - Przywróć Monikę
źródło