Celem tego pytania jest odpowiedź na ciekawość, a nie rozwiązanie konkretnego problemu komputerowego. Pytanie brzmi: dlaczego obowiązkowe narzędzia POSIX nie są często wbudowane w implementacje powłoki?
Na przykład mam skrypt, który w zasadzie czyta kilka małych plików tekstowych i sprawdza, czy są one odpowiednio sformatowane, ale uruchomienie na moim komputerze zajmuje 27 sekund z powodu znacznej ilości operacji na łańcuchach. Ta manipulacja ciągiem powoduje tysiące nowych procesów poprzez wywoływanie różnych narzędzi, stąd powolność. Jestem całkiem pewny, że jeśli niektóre media zostały wbudowane, a mianowicie grep
, sed
, cut
, tr
, i expr
, a następnie skrypt zostanie uruchomiony w sekundę lub mniej (w oparciu o moje doświadczenia w C).
Wydaje się, że byłoby wiele sytuacji, w których wbudowanie tych narzędzi sprawiłoby różnicę między tym, czy rozwiązanie w skrypcie powłoki ma akceptowalną wydajność.
Oczywiście istnieje powód, dla którego nie zdecydowano się na wbudowanie tych narzędzi. Być może posiadanie jednej wersji narzędzia na poziomie systemu pozwala uniknąć używania wielu różnych wersji tego narzędzia przez różne powłoki. Naprawdę nie mogę wymyślić wielu innych powodów, aby utrzymać narzut związany z tworzeniem tak wielu nowych procesów, a POSIX wystarczająco definiuje narzędzia, że różne implementacje nie wydają się dużym problemem, o ile każdy z nich jest POSIX zgodny. Przynajmniej nie tak duży problem, jak nieefektywność posiadania tak wielu procesów.
printf
itp.) Zostały włączone do powłok, gdy uznano je za wystarczająco użyteczne.awk
to obowiązkowe narzędzie w POSIX, a szczególnie dobrze nadają się (czyli bardzo szybki) w celu wdrożenia skryptów, które można realizować w inny sposób za pomocąsed
,cut
,tr
,grep
, iexpr
w skrypcie powłoki.Odpowiedzi:
Skrypty powłoki nie powinny działać z taką prędkością. Jeśli chcesz poprawić szybkość skryptu, wypróbuj go w Perlu. Jeśli nadal jest to zbyt wolne, musisz przejść do języka o typie statycznym, takiego jak java lub c, lub napisać moduł C dla perla, który uruchamia zbyt wolne części.
Shell to pierwszy poziom prototypowania, jeśli możesz udowodnić tę koncepcję za pomocą powłoki, to przejdź do lepszego języka skryptowego, który może wykonać więcej sprawdzania granic, co zająłoby akry powłoki.
Oczekuje się, że system operacyjny Unix będzie zawierać wiele małych programów, które wykonują dobrze zdefiniowane zadania, które składają się na większy obraz. To dobra rzecz, ponieważ dzieli większe programy na części. Spójrz na przykład na qmail i porównaj to z sendmailem. qmail składa się z wielu programów:
http://www.nrg4u.com/qmail/the-big-qmail-picture-103-p1.gif
Wykorzystanie demona sieciowego nie pomoże w wykorzystaniu menedżera kolejek.
źródło
cd
lubpwd
.cd
jest wbudowany - i tak musi być, ponieważ zmiana katalogu roboczego w podprocesie nie wpływa na procesy nadrzędne.Aby być zgodnym z POSIX, wymagany jest system 1, aby zapewnić większość narzędzi jako samodzielne polecenia.
Zainstalowanie ich oznaczałoby, że muszą istnieć w dwóch różnych lokalizacjach, wewnątrz powłoki i poza nią. Oczywiście możliwe byłoby zaimplementowanie wersji zewnętrznej za pomocą otoki skryptu powłoki do wbudowanego narzędzia, ale niekorzystnie wpłynęłoby to na aplikacje nie powłoki wywołujące narzędzia.
Zauważ, że BusyBox podążył ścieżką, którą zasugerowałeś, implementując wiele poleceń wewnętrznie i udostępniając samodzielny wariant za pomocą łączy do siebie. Jednym z problemów jest to, że zestaw poleceń może być dość duży, implementacje są często podzbiorem standardu, więc nie są zgodne.
Należy również zauważyć, że co najmniej
ksh93
,bash
izsh
pójść dalej poprzez zapewnienie niestandardowe metody dla uruchomionej powłoce dynamicznie builtins ładunek z bibliotek współdzielonych. Technicznie nic nie stoi na przeszkodzie, aby wszystkie narzędzia POSIX zostały zaimplementowane i udostępnione jako wbudowane.Wreszcie, tworzenie nowych procesów stało się dość szybką operacją w przypadku nowoczesnych systemów operacyjnych. Jeśli naprawdę odczuwasz problem z wydajnością, możesz wprowadzić ulepszenia, aby skrypty działały szybciej.
1 POSIX.1-2008
źródło
fork
nie, po którym następujeexec
;fork
jest obecnie bardzo lekką operacją w porównaniu doexec
.nofork
wbudowane busybox mają 10-krotnie mniejszy narzut niżnoexec
wbudowane, które z kolei miały ~ 5-krotnie mniejsze obciążenie niż rozwidlenie + wykonanie osobnego pliku binarnego. Definicje według unix.stackexchange.com/a/274322/29483 Interesujące jest to, że busybox nienofork
wszystko, chociaż wiem, że niektóre kody busybox są skracane przez brak czyszczenia pamięci i po prostu polegają na tym, że są krótkotrwałe.Z podręcznika BASH ,
Jak jestem pewien, słyszałeś, filozofia UNIX opiera się w dużej mierze na wielu aplikacjach, które mają ograniczoną funkcjonalność. Każdy wbudowany ma bardzo dobry powód, dla którego jest wbudowany. Nie wszystko inne. Myślę, że bardziej interesująca klasa pytań brzmi: „dlaczego dokładnie jest
pwd
wbudowana?”źródło
cd
byłby to lepszy przykład czegoś, czego nie można wdrożyć jako osobnego narzędzia.cd
musi być wbudowany,pwd
nie. Dlaczego więcbash
implementatorzy zdecydowali się to uwzględnić?/bin/bash
istnieje, ale wciąż jest wbudowany. Zobacz listę wbudowanych plików na gnu.org/software/bash/manual/html_node/…Faceci w AT&T zadawali sobie to samo
Jeśli spojrzysz na historię oprogramowania AT&T Software Toolkit (obecnie nieaktywnego na githubie od czasu odejścia zespołu podstawowego), dokładnie to zrobili z powłoką AT&T Korn, czyli ksh93.
Wydajność zawsze była motywacją dla opiekunów ksh93, a podczas budowania ksh możesz zbudować wiele popularnych narzędzi POSIX jako dynamicznie ładowanych bibliotek. Wiążąc te polecenia z nazwą katalogu, na przykład
/opt/ast/bin
, możesz kontrolować, która wersja polecenia będzie używana, na podstawie położenia tej nazwy katalogu w$PATH
.Przykłady:
Pełna lista znajduje się w repozytorium github ast .
Zauważ, że większość narzędzi ast ma swoje pochodzenie i różni się znacznie od bardziej powszechnych implementacji GNU. Zespół badawczy AT&T przestrzegał oficjalnych standardów, co było sposobem na osiągnięcie interoperacyjności, gdy nie można było współdzielić kodu.
źródło
Dlatego nie zgromadziliśmy środków na optymalizację oryginalnego narzędzia, aby spełnić każde konkretne pragnienie. Wydaje mi się, że musimy wyjaśnić, ile kosztowało by to konkretne pragnienie.
jest to złe założenie :-P.
Systemy Post-POSIX stają się coraz bardziej wydajne i wygodne z dobrych powodów; jako standard po fakcie nigdy nie nadrabia zaległości.
Ubuntu podjął starania, aby przejść do zredukowanej powłoki POSIX dla skryptów, aby zoptymalizować stary proces uruchamiania systemu w wersji V. Nie twierdzę, że to się nie udało, ale spowodowało wiele błędów, które musiały zostać usunięte: „bashisms”, skrypty, które działały pod warunkiem,
/bin/sh
żebash
funkcje były dostępne.POSIX sh nie jest dobrym językiem programowania ogólnego przeznaczenia. Jego głównym celem jest sprawne działanie jako interaktywna powłoka. Jak tylko zaczniesz zapisywać polecenia w skrypcie, pamiętaj, że zbliżasz się do tarasu Turinga . Np. Nie można wykryć awarii w środku normalnego rurociągu .
bash
dodanoset -o pipefail
w tym celu, ale nie jest to POSIX.Podobne przydatne, ale niestandaryzowane funkcje są oferowane przez prawie każde narzędzie bardziej złożone niż
true
.Dla zarysowanej klasy zadania możesz narysować szorstką linię dla Awk, Perl, a obecnie Python. Różne narzędzia zostały stworzone i ewoluowały niezależnie. Czy spodziewałbyś się, że np. GNU Awk zostanie włączony do libutilposixextended?
Nie twierdzę, że mamy teraz jedno ogólnie lepsze podejście, na które mogę wskazać. Mam słabość do Pythona. Awk jest zaskakująco potężny, chociaż byłem sfrustrowany niektórymi cechami specyficznymi dla GNU Awk. Ale chodzi o to, że przetwarzanie dużej liczby łańcuchów osobno (prawdopodobnie z linii plików) nie było celem projektowym powłoki POSIX.
źródło
cat -@fnord foo
powłoka powinna o tym zadecydować, ponieważ nie wie, co to-@
znaczy, musiałaby wywołać rzeczywiste polecenie, ale biorąc pod uwagę samącat <foo >bar
powłokę, nie trzeba jej odradzać.Pozostaje również pytanie: w którą powłokę chcesz go wbudować?
Większość systemów Unix / Linux ma wiele różnych powłok, które są opracowywane niezależnie (sh / bash / korn / ???). Jeśli wbudujesz narzędzia w powłokę, skończysz z inną implementacją tych narzędzi dla każdej powłoki. Spowodowałoby to narzut i możesz skończyć z różnymi funkcjami / błędami, na przykład grep, w zależności od powłoki, której użyłeś do wywołania.
źródło
Wielu odpowiedziało dobrze. Zamierzam jedynie uzupełnić te odpowiedzi. Myślę, że filozofią UNIX jest to, że narzędzie powinno zrobić jedną rzecz i zrobić to dobrze. Jeśli ktoś próbuje stworzyć wszechstronne narzędzie, jest więcej miejsc do porażki. Ograniczenie funkcjonalności w ten sposób sprawia, że zestaw narzędzi jest niezawodny.
Zastanów się również, czy jeśli funkcjonalność, taka jak sed lub grep, została wbudowana w powłokę, czy równie łatwo byłoby wywołać ją z wiersza poleceń, kiedy chcesz?
Podsumowując, zastanów się, niektóre funkcje, które chcesz być w BASH, są w BASH . Na przykład, zdolność dopasowywania RE w BASH jest zaimplementowana przy użyciu operatora binarnego = ~ (zobacz Gramatyka powłoki na stronie podręcznika, aby uzyskać więcej informacji, w szczególności omówienie konstrukcji [[]] dla if ). Jako bardzo szybki przykład załóżmy, że szukam w pliku 2 cyfr szesnastkowych:
Jeśli chodzi o funkcjonalność podobną do sed , spójrz pod Rozwijanie parametrów w nagłówku Rozbudowa tej samej strony podręcznika. Zobaczysz wiele rzeczy, które możesz zrobić, które przypominają sed. Najczęściej używam sed, aby dokonać zmiany typu podstawienia w tekście. Uwzględniając powyższe:
W końcu jednak, czy powyższe jest „lepsze” niż?
źródło
To chyba historyczny wypadek.
Kiedy UNIX powstał na przełomie lat sześćdziesiątych i siedemdziesiątych XX wieku, komputery nie miały prawie tyle pamięci, co obecnie. W tym czasie byłoby możliwe zaimplementowanie wszystkich tych funkcji jako wbudowanych powłok, ale z powodu ograniczeń pamięci musieliby ograniczyć liczbę funkcji, które mogliby wdrożyć, lub ryzykować brak pamięci i / lub zamianę śmieci problemy.
Z drugiej strony, wdrażając daną funkcjonalność jako osobne programy i wykonując dwa wymagane wezwania systemowe do rozpoczęcia nowego procesu tak łagodnie, jak to możliwe, mogą stworzyć środowisko skryptowe, które nie ma tych problemów i które nadal działa na rozsądnym poziomie prędkość.
Oczywiście, gdy te rzeczy zostaną zaimplementowane jako osobne procesy, ludzie uruchomią je z programów, które nie są powłokami, a następnie muszą tak pozostać, albo nagle całe to oprogramowanie zacznie się psuć.
Nie oznacza to jednak, że nie można dwukrotnie zaimplementować niektórych funkcji, a niektóre powłoki implementują funkcje, które powinny być programami zewnętrznymi jako wbudowane powłoki; np. bash implementuje
echo
polecenie jako wbudowane, ale jest też/usr/bin/echo
źródło