Co to jest powłoka i jakie są
Po tej lekcji: kursant wie, czym jest powłoka, rozróżnia sh, Bash, zsh, fish i dash, sprawdza, której używa, umie ją zmienić i rozumie, czemu skrypt napisany pod Basha może nie zadziałać w sh.
Wstęp
Mac, otwarty Terminal, napis eryk@MacBook ~ %
Otwierasz terminal na Macu, a tam zamiast dolara jest procent. Kopiujesz komendę z tutoriala o Bashu, a ona robi coś innego. Wklejasz skrypt z internetu na serwer, a on wywala się w drugiej linijce z błędem [[: not found.
To nie złośliwość. To znak, że rozmawiasz z innym urzędnikiem. Dziś poznasz całą rodzinę.
Co to jest powłoka
Pamiętasz urząd z pierwszej lekcji? Terminal to okienko, a za szybą siedzi urzędnik, który czyta Twoje wnioski i je wykonuje. Ten urzędnik to powłoka, po angielsku shell.
Czemu „powłoka”? Bo otacza jądro systemu jak skorupa orzech. Jądro to część, która naprawdę rządzi sprzętem: pamięcią, dyskiem, procesorem. Ale z jądrem nie da się porozmawiać po ludzku. Powłoka tłumaczy Twoje „pokaż pliki” na prośby, które jądro rozumie.
I teraz ważne: powłoka to zwykły program. Taki sam jak ls czy grep. Można ją wymienić na inną, jak dostawcę internetu. Dlatego powłok jest wiele.
echo $SHELL
echo $0
ps -p $$$SHELL mówi, jaką powłokę masz ustawioną na start. $0 i ps -p $$ mówią, która powłoka teraz z Tobą rozmawia. To nie zawsze to samo. Możesz mieć ustawionego zsh, a w środku odpalić Basha.
Rodzina urzędników
sh, czyli Bourne shell. Dziadek. Napisał go Stephen Bourne w Bell Labs, wszedł do Uniksa w 1979 roku. Prosty, surowy, bez wygód. Na jego zasadach oparto standard POSIX, czyli wspólny język, który rozumie każda powłoka z tej rodziny. Jak łacina dla języków romańskich.
Bash. Ojciec, który odziedziczył firmę. Brian Fox napisał go dla projektu GNU w 1989 roku jako wolny zamiennik powłoki Bourne'a. Stąd nazwa: Bourne Again SHell. Rozumie wszystko, co sh, plus masę udogodnień: historię, Tab, tablice, [[ ]]. Domyślny na większości Linuksów i na prawie każdym serwerze. Dlatego uczymy się właśnie jego.
zsh. Kuzyn, który chodzi na siłownię. Paul Falstad, 1990 rok. Bardzo podobny do Basha, ale z lepszym podpowiadaniem, poprawianiem literówek i wtyczkami. Od macOS Catalina z 2019 roku to domyślna powłoka na każdym Macu. Stąd ten procent w znaku zachęty.
fish. Młodszy brat z Doliny Krzemowej. Nazwa od „friendly interactive shell”, przyjazna powłoka interaktywna. Kolorowa, sama podpowiada komendy, zanim skończysz pisać. Ale celowo nie trzyma się wspólnego języka. Zwykłe przypisanie zmiennej z Basha wywala w fish błąd:
fish: Unsupported use of '='. In fish, please use 'set x 5'.Świetny do codziennej pracy na własnym laptopie. Do skryptów na serwery zupełnie nie.
dash. Szybki, chudy kurier. Na Ubuntu od 2006 roku i na Debianie od wersji 6 to właśnie on odpowiada na nazwę sh. Umie tylko wspólny język POSIX, za to robi to szybciej niż Bash. Przy starcie systemu uruchamia się tysiące małych skryptów, więc każda zaoszczędzona milisekunda się liczy.
readlink -f /bin/shNa Ubuntu odpowiedź to /usr/bin/dash. Plik sh jest drogowskazem do dasha.
ksh i csh. Wujkowie z innych gałęzi. ksh, czyli KornShell Davida Korna, jeszcze żyje w starych systemach bankowych i na niektórych Uniksach. csh Billa Joya ma składnię podobną do języka C. Spotkasz je rzadko, ale kiedy spotkasz, przynajmniej będziesz wiedział, czemu nic nie działa.
Która powłoka może się logować
cat /etc/shellsTo lista powłok, które system uznaje za prawidłowe do logowania. Poza Bashem i dashem zobaczysz może rbash, czyli Basha z ograniczeniami, dla użytkowników, którym wolno tylko trochę. A czasem nawet tmux, który powłoką nie jest, ale zapisał się na listę, żeby można go było ustawić na start.
Zmiana powłoki na stałe:
chsh -s /usr/bin/zshchsh to „change shell”. Zadziała po ponownym zalogowaniu. I zadziała tylko z powłoką, która jest w /etc/shells.
Czemu to ważne dla admina: pierwsza linijka skryptu
Za kilkanaście lekcji napiszesz pierwszy skrypt. Pierwsza linijka będzie wyglądać tak:
#!/bin/bashTa linijka mówi systemowi, którego urzędnika zawołać do wykonania pliku. I tu jest pułapka. Popatrz:
#!/bin/sh
if [[ "a" == "a" ]]; then echo tak; fiNa Ubuntu ten skrypt wypisze:
[[: not foundBo [[ ]] to wynalazek Basha. Napisałeś #!/bin/sh, więc system zawołał dasha. A dash zna tylko wspólny język. To jak wysłanie do urzędnika z Lizbony wniosku po hiszpańsku. Podobne, ale nie to samo.
Co gorsza, skrypt nie przerwał się z hukiem. Wypisał błąd i jechał dalej, jakby nic. A kod wyjścia całego skryptu to zero, czyli „wszystko dobrze”. Na ekranie przy biurku to zauważysz. W nocy, w automacie, nikt tego nie zobaczy.
Rzeczy, które działają w Bashu, a nie w czystym sh, nazywa się „bashizmami”. Zasada jest prosta: używasz rzeczy z Basha, to piszesz #!/bin/bash. Koniec.
Jak to działa pod spodem
Kiedy otwierasz terminal, program terminala uruchamia powłokę. Którą? Tę z ostatniego pola Twojej linijki w /etc/passwd. To samo pole, z którego robiłeś ranking w zadaniu z lekcji 7.
grep "^$USER:" /etc/passwdPowłoka startuje, czyta swoje pliki ustawień, wypisuje znak zachęty i czeka. Wpisujesz komendę, ona ją czyta, rozkłada na części i uruchamia. Jak dokładnie to robi, krok po kroku, zobaczysz w następnej lekcji.
A kiedy uruchamiasz skrypt, jądro czyta pierwsze dwa znaki pliku. Jeśli to #!, bierze resztę linijki jako ścieżkę do programu, który ma ten plik wykonać. Ta para znaków ma nawet swoją nazwę: shebang.
Bash na Macu
Na Macu jest i zsh, i Bash. Ale ten Bash ma wersję 3.2 sprzed prawie dwudziestu lat. Nowsze wersje Basha mają licencję GPLv3, której Apple nie chce u siebie. Więc zamiast zaktualizować, Apple w 2019 roku przesadziło wszystkich na zsh.
Dlatego jeśli uczysz się na Macu, zainstaluj nowego Basha przez Homebrew (brew install bash) albo pracuj na Linuksie w maszynie wirtualnej. Bash 3.2 nie zna na przykład słowników, które poznamy w module o danych.
Ściąga
| Komenda | Co robi |
|---|---|
echo $SHELL | powłoka ustawiona na start |
echo $0 | powłoka, która działa teraz |
ps -p $$ | to samo, przez listę procesów |
cat /etc/shells | dozwolone powłoki logowania |
chsh -s /ścieżka | zmienia powłokę na stałe |
readlink -f /bin/sh | pokazuje, kim naprawdę jest sh |
bash --version | wersja Basha |
bash, zsh, sh | uruchamia daną powłokę w środku obecnej, wyjście przez exit |
| Powłoka | Gdzie ją spotkasz | Do czego |
|---|---|---|
| sh (dash) | /bin/sh na Ubuntu i Debianie | skrypty systemowe, maksymalna przenośność |
| Bash | prawie każdy Linux i serwer | codzienna praca i skrypty admina |
| zsh | domyślnie na Macu | wygodna praca w terminalu |
| fish | instalowany ręcznie | wygodna praca, nie do skryptów |
| ksh, csh, tcsh | stare Uniksy, banki | spotkasz, nie wybierzesz |
⚠ Typowy błąd
sh moj_skrypt.shSkrypt ma w środku #!/bin/bash, ale uruchomiłeś go przez sh. Wtedy pierwsza linijka jest ignorowana, bo sam wskazałeś urzędnika. I znowu dash czyta Basha. Uruchamiaj skrypty przez ./moj_skrypt.sh albo bash moj_skrypt.sh.
✎ Zadanie
- Sprawdź, jakiej powłoki używasz teraz i jaka jest ustawiona na start.
- Sprawdź, kim jest
shw Twoim systemie. - Wpisz
sh, a potemecho {1..3}. Wyjdź przezexiti zrób to samo w Bashu. Porównaj wyniki i zastanów się, co z tego wynika.
Pokaż rozwiązanie
echo $0
echo $SHELL
readlink -f /bin/sh
sh
echo {1..3}
exit
bash
echo {1..3}
exitU mnie na Ubuntu:
bash
/bin/bash
/usr/bin/dash
{1..3}
1 2 3$0 mówi, kto rozmawia z Tobą teraz, $SHELL, kto jest ustawiony na start. sh to na Ubuntu drogowskaz do dasha. A dash na {1..3} odpowiada dokładnie tym, co dostał: {1..3}. Nawiasy klamrowe to wynalazek Basha, dash ich nie zna, więc oddaje napis jak urzędnik, który dostał formularz w obcym języku i po prostu go odsyła. Bash rozwija to w 1 2 3.
[RHEL] Na Red Hacie, Rocky i Almie readlink -f /bin/sh pokaże /usr/bin/bash, a sh wypisze 1 2 3. Bash udający sh dalej rozumie klamry. Dlatego skrypt, który „działa u mnie”, na Ubuntu potrafi się wyłożyć.
Co dalej
Wiesz już, kim jest urzędnik. W następnej lekcji zaglądamy mu przez ramię. Co dokładnie robi Bash od momentu, kiedy naciskasz Enter, do chwili, gdy komenda rusza. Kolejność, w której zamienia gwiazdki, zmienne i cudzysłowy. Bez tego nie da się zrozumieć połowy dziwnych błędów w skryptach.