Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Zrozumieć powłokę tekstową - troszkę historii

Po przeczytaniu wpisu kolegi roobal'a Terminal w Linux - obiekt nienawiści użytkowników systemu Windows postanowiłem napisać jeszcze coś od siebie w komentarzu, ale po chwili stwierdziłem, że mam znacznie więcej do powiedzenia. Otóż większość ludzi, których spotykałem i którym zadawałem pytanie "Czy wiesz co to powłoka systemowa?" - robiło wielkie oczy. Jak widzą jak wklepuje polecenia na "czarnym ekranie" to nie rozumieją dlaczego nie chce używać myszki. Ale żeby naprawdę zrozumieć dlaczego to robię, to należy zagłębić się nieco w historię powłok i poznać ich zalety i w ogóle dowiedzieć się co to jest. Zatem do dzieła.

Każdy komputer to zwykła kupa elektroniki, która bez odpowiedniego oprogramowania jest po prostu bezużyteczna. Dlatego też musi być wyposażony w system operacyjny, który "wie" jak obsłużyć sprzęt i jak komunikować się z człowiekiem. To pierwsze robi jądro systemu, a drugie powłoka. I na tym można skończyć, ale ja jestem nieco ambitniejszy :) i postaram się jeszcze czegoś Was drodzy Czytelnicy nauczyć.

W latach sześćdziesiątych XX wieku większość systemów operacyjnych, uruchamianych na ówczesnych komputerach, miało charakter wsadowy. Nie istniały jeszcze znane dzisiaj nośniki informacji, dlatego do wprowadzania danych do komputera używano kart perforowanych. Operator takiej maszyny najpierw musiał wczytać karty z programem, a następnie w ten sam sposób dane. Wyniki na ogół przekazywane były w formie wydruku, a następnie analizowane. Jeżeli zauważono jakieś błędy to cały proces należało powtórzyć. Nie trudno zauważyć, że procesory używane w tamtych maszynach w 95% nic nie robiły, bo przygotowanie wsadowych kart perforowanych zajmowało bardzo dużo czasu. Dlatego projektanci rozpoczęli prace nad systemem, który byłby wyposażony w interpreter umożliwiający operatorowi możliwość sterowania pracą programów poprzez wydawanie poleceń. Jednocześnie pracowano nad systemem umożliwiającym uruchamianie równolegle wielu programów przez wielu operatorów. Nie będę tutaj wdawał się w szczegóły techniczne poszczególnych systemów, napisze tylko, że pierwszym takim systemem był CTSS (ang. Cray Time Sharing System), później MULTICS (ang. Multiplexed Information and Computing Service), aż w końcu jeden z twórców MULTICS'a - Ken Thompson razem z Dennisem Ritchie napisali pierwszego UNIX’a.

I zanim o powłoce to troszkę o UNIX'e. UNIX przejął wiele cech MULTICS’a. Chodzi tu głównie o umowne reprezentowanie urządzeń plikami i wyodrębnienie interpretera poleceń, czyli celowo nie integrowano powłoki z samym systemem operacyjnym. Komputery PDP-11, na których system UNIX miał być uruchamiany, nie były zdolne do wykonywania obszernych programów. Realizacja założonych zadań wymagała ich podziału na mniejsze jednostki zadaniowe wykonywane poprzez wywołania odpowiednich programów. Ostatecznie ograniczona przestrzeń adresowa architektury maszyn goszczących system przyczyniła się do powstania mniejszych, prostszych, ale za to bardzo wyspecjalizowanych programów.
Skoro wszystko jest plikiem (a nawet to co nim nie jest - jak dodają złośliwi) to obsługa całego systemu sprowadza się do edycji plików. Należy pamiętać, że wtedy nie znano jeszcze GUI więc tworzono tysiące narzędzi tekstowych do edycji plików. Skoro tak, to z czasem powłoki systemowe wyposażono w te narzędzia. Aż wreszcie w 1977 roku niejaki Pan Stephena Bourne udostępnił własną powłokę dla systemu UNIX, którą nazwana powłoką Bourne'a, chociaż lepiej znana jest pod nazwą sh. Powłoka ta była rewolucyjnym rozwiązaniem, bo umożliwiała tworzenie i uruchamianie w niej skryptów! To bardzo istotna funkcjonalność bo wreszcie można było napisać skrypt (w języku programowania powłoki), w którym dało się automatycznie edytować tekst wykorzystując istniejące już, specjalizowane narzędzia. Ponadto użytkownik miał pełną kontrolę nad deskryptorami wejścia/wyjścia oraz przepływem danych.

Poniżej postaram się wyjaśnić jak to działa i co to nam daje za pomocą bardzo prostego polecenia.

cat tekst.txt | grep stokrotka >> nowytekst.txt

cat tekst.txt - proste polecenie wyświetlenia tekstu na ekranie. W praktyce działa to tak, że zawartość pliku tekst.txt jest kierowana na standardowy strumień wyjściowy (STDOUT), czyli na ekran. Ale można to poddać modyfikacji za pomocą operatora potoku "|". Działa to tak, że STDOUT polecenia cat jest kierowany na standardowy strumień wejściowy (STDIN) polecenia grep. (Warto zauważyć, że grep nie jest poleceniem wbudowanym w powłokę, ale zupełnie oddzielnym programem mającym własne parametry.) Ten z kolei wyszukuje w tekście słowa "stokrotka" i na STDOUT (czyli na ekran) kieruje jedynie wiersze, w których to słowo występuje. Ale tutaj napotykamy na operator przekierowania strumienia ">>", który zmienia STDOUT na plik o nazwie nowytekst.txt. Finalnie w pliku nowytekst.txt otrzymujemy tylko wiersze z pliku tekst.txt zawierające wyraz "stokrotka".

A teraz zastanówmy się nad tym ile czasu potrzebujemy żeby ten sam program napisać np. w języku C?

Po raz kolejny przypominam, że obsługa całego systemu polega na edycji plików, co możemy zrobić bezpośrednio z konsoli mając do dyspozycji tysiące narzędzi typu grep. Czyli reasumując, możemy w konsoli zrobić dosłownie wszystko!
Biorąc pod uwagę fakt, że do dyspozycji mamy wiele innych powłok np. ksh, csh czy bash, które są tylko ulepszeniem powłoki sh, to otrzymujemy w pełni funkcjonalne narzędzie do administrowania systemem.

W systemach Microsoftu też są konsole tekstowe. Np. command.com dla sytemu DOS, czy cmd.exe dla systemu Windows, czy wreszcie PowerShell, za pomocą którego podobno można wykonać każde zadanie administracyjne w systemie Windows. Korzysta się z nich właśnie dlatego, że pewnie zadania można wykonać po prostu szybciej wpisując proste polecenia. Dla przykładu podam ot choćby sprawdzanie naszego adresu IP i MAC karty sieciowej w Windows. Kto z Was robi to inaczej niż uruchamiając powłokę cmd i wklepując polecenie ipconfig /all? I dlaczego nie spotkałem jeszcze nikogo, kto robi to inaczej? Ale w Windows mało kto na co dzień używa powłoki tekstowej, bo po prostu niewiele da się w niej zrobić (wyłączając PowerShell). Poza tym, Okienka są tworzone do obsługi klikanej, a polecenia tekstowe są niejako dodawane na siłę. Zupełnie inaczej jest w UNIX'ach. Tutaj niemal wszystko jest tworzone do obsługi z poziomu konsoli, a do tego dodawany jest interfejs GUI.

Podsumowując odpowiem wreszcie na pytanie "dlaczego terminal jest obiektem nienawiści użytkowników Windows".
Bo w cmd.exe nie da się administrować systemem, a PowerShell jest mało znany (i według mnie nieintuicyjny). Zatem z punktu widzenia "Windowsiarza" konsola tekstowa jest po prostu zbędna. Dlatego polecam nauczyć się PowerShell i wtedy zobaczymy, czy terminal śmierdzi :).

Na zakończenie chciałbym zaproponować serię artykułów o powłoce bash i jej języku skryptowym. Tak się składa, że bash był tematem mojej pracy magisterskiej i mam sporo na jej temat do powiedzenia :)

Pozdrawiam 

Komentarze

0 nowych
c0m4r   5 #1 06.06.2010 19:16

Obawiam się, że laik niczego z Twojego wpisu nie wyniesie, ponieważ większości opisanych pojęć nie zrozumie.
"Troszkę historii", to adekwatny podtytuł, tytuł - mniej.

Pozdrawiam

Fanboj O   6 #2 06.06.2010 19:32

Uuuuu. Artykuł z zupełnie innej ligi. Najlepszy jaki czytałem na blogu.dp.
Odnośnie historii, to jest ona jednak nauczycielką życia. Najlepiej można poznać ideę komputera, kiedy zaczyna się w nią zgłębiać od właśnie historycznych systemów, architektur i sprzętów.
Nie zna komputerów ten, co nie zahaczył choćby o DOS...
Oczywista młode pokolenie reaguje buntem na próby uczenia na zaprzeszłościach. Od razu chcieliby Win x64, C++ Builder, Photoshop...

  #3 06.06.2010 19:38

Interesujący artykuł z niecierpliwością czekam na kolejne :)

  #4 06.06.2010 20:24

Po przeczytaniu tego tekstu, to nie wiem, czy jako laik zrozumiałbym czym jest desktryptor, STDIN, STDOUT, itd.

JanStefan   6 #5 06.06.2010 20:44

O to chodzi, że jeżeli ktoś jest laikiem, a temat go interesuje to sobie sprawdzi co dane słowo oznacza. Tekst dobry, czytelnie napisany, a braki w wiedzy szybko można nadrobić by tekst zrozumieć w 100%

Podsumowując, tekst który czegoś uczy, no i jest dobrym wstępem. Czekam na rozwinięcie tematu.

trux   11 #6 06.06.2010 22:12

Bardzo dobry wpis, pokazujący jak ogromne możliwości ma tzw konsola.
Przydały by się opisy: strumieni, potoków, przekierowań oraz procesów uruchamianych w tle.

borzole   4 #7 06.06.2010 22:16

"bash był tematem mojej pracy magisterskiej i mam sporo na jej temat do powiedzenia :)"

No to ja mam pytanie :)

* Co zrobić, aby skrypt uruchomiony z konta root mógł przyjąć sygnał przerwania
# trap funkcja_blabla 35
wysłany przez zwykłego użytkownika?
$ kill -s 35 $PID_SERVER
Chodzi o działanie typu client-server. Jeśli oba skrypty są uruchomione z jednego konta, wszystko działa, ale nie w przypadku kiedy serwer działa z konta root. Mam na to ładne dłuższe obejście (komunikacja klienta przez "mkfifo -m 622" z serwerem nasłuchującym, który dopiero wysyła przerwania do serwera głównego), ale szukam czegoś bezpośredniego.

* Jeśli raz przekieruje deskryptor 1 i 2
$ exec 1> >(jakas_funkcja_czytajaca)
$ exec 2>&1
to jak to potem rozdzielić i przywrócić do normalnego stanu ?

  #8 06.06.2010 23:01

@borzole | 06.06.2010 22:16 : Sygnały użytkownika? Wiem, że to tak niestandardowo i w ogóle, ale będzie działać.

Chomik   4 #9 06.06.2010 23:54

Oj, toś kolego sympatyczny dowalił teraz z grubej rury. Mówiąc wprost nie wiem jak to zrobić, ale mogę się dokształcić i pomóc. Na razie odsyłam do książki pt. Bash - Receptury do rozdziału 10.6 - "Przechwytywanie przerwań". A jak tam nie ma to pozostaje chyba tylko dokumentacja bash'a.

  #10 07.06.2010 00:51

cat plik.txt | grep xxx >> nowy.txt

A nie lepiej:
grep plik.txt xxx >> nowy.txt

I pozbylismy sie wolnego potoku :)

  #11 07.06.2010 01:03

Artykuł, choć pobieżnie traktujący temat bardzo mi się spodobał. Spodobało mi się porównanie czasu pisania instrukcji przedstawionej w bloku z adekwatną ilością czasu przy pisaniu tego w C ;)

Soren   8 #12 07.06.2010 08:04

Dobrze się czytało na rozbudzenie :)
Chętnie poczytam także o bashu ;)

Pozdrawiam

Soren   8 #13 07.06.2010 08:04

Dobrze się czytało na rozbudzenie :)
Chętnie poczytam także o bashu ;)

Pozdrawiam

Pigmej   5 #14 07.06.2010 08:29

Wczoraj pisałem jako "niezalogowany" ale chyba napisałem odwrotnie.

No wiec jeszcze raz:
"cat tekst.txt | grep stokrotka >> nowytekst.txt" tak nie musimy... potok w tym miejscu jest zbędny

to samo mozemy zrobic
"grep stokrotka tekst.txt >> nowytekst.txt"

:)

nintyfan   10 #15 07.06.2010 09:15

Mój komentarz się nie pojawił.

Ja bym wykorzystał sygnał użytkownika, ale to rozwiązanie niestandardowe.

Zresztą, to istnieje DBUS, za pomocą którego na pewno da się to rozwiązać.

borzole   4 #16 07.06.2010 14:15

@nintyfan
* dbus jest tylko rozbudowaną ideą mkfifo i tutaj nic nie zmienia, bo w obydwu przypadkach serwer cały czas musi nasłuchiwać. Chciałbym, aby nasłuchiwał tylko na żądanie.

* sygnał użytkownika tez nie chce współgrać, chyba że ja coś źle robię:
http://dl.dropbox.com/u/409786/pub/home/arch/forum/trap-server.sh
http://dl.dropbox.com/u/409786/pub/home/arch/forum/trap-client.sh

  #17 07.06.2010 14:34

Pigmej, oczywiście zgadzam się z Tobą, że tą samą czynność można wykonać nieco inaczej (tak jak Ty proponujesz), ale to świadczy wyłącznie o elastyczności i uniwersalności powłoki. Prawda jest taka, że i jeden i drugi sposób charakteryzuje się małym nakładem pracy w porównaniu do tradycyjnych języków kompilowanych. Wcale to nie oznacza, że komputer będzie je wykonywał szybciej. Jest wręcz przeciwnie. Skrypty powłoki są wolniejsze ale się je szybciej pisze.

  #18 07.06.2010 17:36

@borzole | 07.06.2010 14:15 : Masz rację, ale np. wykorzystanie takiego wywołania systemowego, jak select nie wchodzi w grę? Jeszcze na Linuksie są procedury odczytu, które czekają na dane w deskryptorze tylko określony czas.

borzole   4 #19 07.06.2010 22:29

@notgnucy (niezalogowany) | 07.06.2010 17:36
Mówisz wciąż o czymś dostępnym z poziomu konsoli, czy o funkcji w C "man 2 select" ?

* Zrobiłem ostatnio minimalistyczny client-server. Uruchomione jako root będzie serwerem, a uruchomione z konta usera klientem.
http://borzole.googlecode.com/hg/bin/zajc.sh
Sprawdza się w sytuacji jednego klienta (w sam raz na desktop, zamiast "sudo" ), ale zastanawiam się czy to ma luki w bezpieczeństwie? Zakładając, że luką nie jest sama udostępniona w menu funkcja.

Chomik   4 #20 07.06.2010 23:06

Jeżeli chodzi o bezpieczeństwo to polecam poczytać o przełącznikach powłoki bash "shopt". Są to przełączniki charakterystyczne dla bash'a. Np. 'shopt -s -o nounset' powoduje traktowanie niezdefiniowanych zmiennych jako błędne odwołania, a nie jak zmienne przechowujące wartości puste; i np. 'shopt -s -o noclobber' nadpisywaniu plików podczas przekierowywania danych. Oczywiście tych przełączników jest kilkadziesiąt. Użycie ich z pewnością zwiększy bezpieczeństwo skryptu.

Chomik   4 #21 07.06.2010 23:07

(w pierwszym poście zapomniałem jednego, ale istotnego słowa :))
Jeżeli chodzi o bezpieczeństwo to polecam poczytać o przełącznikach powłoki bash "shopt". Są to przełączniki charakterystyczne dla bash'a. Np. 'shopt -s -o nounset' powoduje traktowanie niezdefiniowanych zmiennych jako błędne odwołania, a nie jak zmienne przechowujące wartości puste; i np. 'shopt -s -o noclobber' zapobiega nadpisywaniu plików podczas przekierowywania danych. Oczywiście tych przełączników jest kilkadziesiąt. Użycie ich z pewnością zwiększy bezpieczeństwo skryptu.

nintyfan   10 #22 07.02.2011 09:03

@borzole | 07.06.2010 22:29 :
read -t ?
Kiedy read niczego nie otrzyma w określonym czasie, to powinien zwrócić określony kod.

nintyfan   10 #23 07.02.2011 09:04

@borzole | 06.06.2010 22:16 :
By coś przywrócić, to by najpierw przydało się to zapamiętać. Nie wolno zapominać, ze Unix pozwala mieć otwartych więcej niż trzy standardowe pliki.