Przejdź do treści
Lekcja 9 z 117

Kurs › Moduł 1 › Lekcja 9

Co to jest powłoka i jakie są

⏱ ok. 7 min czytania· moduł 1: Praca w powłoce

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/sh

Na 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/shells

To 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/zsh

chsh 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/bash

Ta 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; fi

Na Ubuntu ten skrypt wypisze:

[[: not found

Bo [[ ]] 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/passwd

Powł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

KomendaCo robi
echo $SHELLpowłoka ustawiona na start
echo $0powłoka, która działa teraz
ps -p $$to samo, przez listę procesów
cat /etc/shellsdozwolone powłoki logowania
chsh -s /ścieżkazmienia powłokę na stałe
readlink -f /bin/shpokazuje, kim naprawdę jest sh
bash --versionwersja Basha
bash, zsh, shuruchamia daną powłokę w środku obecnej, wyjście przez exit
PowłokaGdzie ją spotkaszDo czego
sh (dash)/bin/sh na Ubuntu i Debianieskrypty systemowe, maksymalna przenośność
Bashprawie każdy Linux i serwercodzienna praca i skrypty admina
zshdomyślnie na Macuwygodna praca w terminalu
fishinstalowany ręczniewygodna praca, nie do skryptów
ksh, csh, tcshstare Uniksy, bankispotkasz, nie wybierzesz

⚠ Typowy błąd

sh moj_skrypt.sh

Skrypt 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

  1. Sprawdź, jakiej powłoki używasz teraz i jaka jest ustawiona na start.
  2. Sprawdź, kim jest sh w Twoim systemie.
  3. Wpisz sh, a potem echo {1..3}. Wyjdź przez exit i 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}
exit

U 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.