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

Zsh, czyli dlaczego warto porzucić Basha

Witam,

Jest to mój pierwszy wpis, więc proszę o wyrozumiałość i/lub sugestie.

Wstęp

Nie podlega wątpliwości, że najpopularniejszą powłoką uniksową jest w dzisiejszych czasach Bash. Wielu użytkowników, również tych doświadczonych, nie zastanawia się, czy nie warto poszukać czegoś lepszego. Tym wpisem chciałbym zachęcić do wypróbowania zsh - moim zdaniem znacznie wygodniejszej alternatywy.

Dlaczego warto spróbować

Na początek chcę zaznaczyć, że zsh jest w dużej mierze kompatybilne z Bashem. Bardzo ułatwia to początki. Większość skryptów powinna działać bez większych przeróbek.

Myślę, że najlepiej będzie jeśli wymienię funkcje, które mi się najbardziej w nim podobają. Bardzo możliwe, że część z nich jest również dostępna w Bashu, ale nie wszystkie. Oto lista:

1) Historia - ignorowane polecenia
Osobiście nie lubię robić syfu w historii wpisywanych komend - jeśli nie zamierzam wpisywać jakiejś komendy po raz kolejny, to nie chcę jej tam mieć. By jakoś to kontrolować, mam włączone, że komendy poprzedzone spacją nie trafiają do historii. Niestety w Bashu ta opcja powoduje, że takiej komendy nie można przywołać strzałką do góry nawet tuż po jej wpisaniu. Zsh pamięta ostatnie wpisaną komendę niezależnie od tego, czy trafiła ona do historii. Bardzo pomocne, gdy zrobi się literówkę.

2) Historia, cz. 2 - współdzielenie historii
Domyślnie, każda uruchomiona powłoka ma swoją własną historię i zapisuje ją dopiero przy zamknięciu. Ma to pewne poważne konsekwencje. Wyobraźmy sobie taką sytuację:
Uruchamiamy powłoki A i B. W A wpisujemy kilka komend i przechodzimy do B. Tam też wpisujemy kilka komend. Zamykamy powłokę A, która zapisuje swoją historię do pliku, nadpisując stary plik z historią nowym. Teraz zamykamy powłokę B, która również... Ups! Chyba straciliśmy polecenia wpisane w powłoce A.
Można takich sytuacji uniknąć poprzez dopisywanie nowych poleceń na bieżąco - tuż po ich wywołaniu. Dodatkowo polecam włączyć doczytywanie historii z pliku po każdym poleceniu i gotowe. Mamy kilka uruchomionych powłok, które dzielą jedną historię. Nie ma mowy o zagubionych komendach.

3) Ulepszony globbing

Zakładam, że wszyscy wiedzą co robi ls *, czy ls *.cpp. Niestety, gdy chcemy wyszukać pliki, które mogą być w podkatalogach, pojawia się problem. Można użyć polecenia find, ale jest to niewygodne. W zsh wystarczy użyć **, np. ls **/Makefile znajdzie nam wszystkie pliki Makefile, które znajdują się w obecnym katalogu lub jego podkatalogach. Znacznie bardziej naturalne niż wywołanie find, prawda?

4) Stringi

W Bashu, jeśli mamy zmienną ABC zawierającą tekst "zsh wymiata" i chcemy wyciąć np. 3 znak (h), to musimy posłużyć się następującą konstrukcją: ${ABC:2:1} - wycinamy 1 znak zaczynając od znaku nr 2 (indeksując od 0). Moim zdaniem nie jest to najwygodniejsze. W zsh możemy się posłużyć składnią zbliżoną do C. Zwykłe $ABC[3] wytnie nam trzeci znak (indeksując od 1). Jeśli chcemy dostać jakiś przedział, np. "zsh", wpisujemy $ABC[1,3]. Dodam, że zsh nie akceptuje tutaj składni Basha.

5) Skrócony which

Polecenie which pozwala sprawdzić, gdzie znajduje się dany program lub skrypt. By szybko edytować skrypt o nazwie abc, można wpisać vim `which abc`. W zsh można to zrobić krócej - vim =abc. Oszczędzamy aż 6 klawiszy!

6) Uzupełnianie poleceń Tabem

Uzupełnianie poleceń - nie da się mówić o zsh i nie wspomnieć o nim.
Mamy taką sytuację: są pliki plikMój1, plikMój2, plikSiostry. Załóżmy, że chcemy otworzyć plikMój1. Bash uzupełni "plik" i nic nie zrobi, aż nie podamy mu czegoś więcej. Wpisujemy M, wciskamy Tab i musimy jeszcze podać 1 lub 2. Gdy zsh ma kilka podobnych plików, można się pomiędzy nimi przełączać Tabem, a - po odpowiedniej konfiguracji - nawet strzałkami. Nie dotyczy to oczywiście jedynie plików - można nawet uzupełniać sobie procesy w poleceniu kill!
Ogólnie, jest to temat-rzeka - ja go tutaj tylko musnąłem.

7) Czepialstwo shella

Tolerancja na zbędne średniki, Bash jej z pewnością nie ma. Przy pisaniu skryptów nie ma to przeważnie znaczenia, ale przy interaktywnym pisaniu pętli czy ifów, już ma. Chcę zrobić np. if [ true ]; then; echo 1; else; echo 2; fiCzego się dowiaduję od Basha? Po then i else nie powinno być średnika (właściwie, to tego się muszę domyślać z niejasnego komunikatu o błędzie). Czego się dowiaduję od zsh? 1. Wiem, że to ja robię błąd składniowy, ale taki zapis wydaje mi się logiczniejszy.

8) Przechowywanie poleceń na później

Jeśli zaczniemy pisać jakieś dłuższe polecenie i nagle zauważymy, że najpierw musimy zrobić coś innego (np. mkdir), w Bashu mamy problem. W zsh wciskamy Alt+Q. To, co wpisaliśmy, znika. Możemy wywołać jakąś inną komendę, a gdy to zrobimy - nasz Pan Tadeusz wraca na swoje miejsce nietknięty.

Druga strona medalu

Nie mówię, że zsh nie ma wad, bo oczywiście ma. Oto kilka z nich:

1) Przenośność

Bash jest niemal wszędzie. Zsh trzeba doinstalować. Sprawia to, że skrypty nie są aż tak przenośne.

2) Początki

Przy domyślnej konfiguracji, Bash wydaje się wygodniejszy. Zsh jest niemal gołe, mimo kreatora.

3) Szybkość (niepotwierdzone)

Podobno zsh jest nieco wolniejsze. Sam tego nie zauważyłem, ale słyszę takie opinie wśród znajomych.

4) Niedoskonałość uzupełniania (lub użytkownika)

Są rzeczy, które Bash uzupełnia, a zsh nie. Pewnie jest to kwestia ustawień, ale nie byłem w stanie znaleźć sensownego tutoriala do ręcznego poprawiania uzupełnień w zsh. Przykładem jest np. pkill, ale tutaj można się posłużyć killem.
EDIT: Tak się zdarzyło, że właśnie wpadł mi w ręce jakiś zrozumiały poradnik pisania funkcji uzupełniania. Już dwie sobie dorobiłem. Dla zainteresowanych - link.

Zakończenie

Każdego, kto spędza dużo czasu w terminalu, zachęcam do wypróbowania zsh. Warto!
Jeśli będzie trzeba, mogę wrzucić swój config.

Do studentów wydziału elektroniki na Polibudzie Warszawskiej: to, co widzicie na jednym z wydziałowych serwerów, nie zasługuje na miano zsh. Jest to wersja sprzed wieków i do tego źle skonfigurowana. Jak cały ten serwer. Jeśli to Was odrzuca od zsh, to niech przestanie - na tym syfie sam używam Basha, bo działa lepiej. Jeden kolega właśnie z tego powodu nie chciał przejść na zsh - aż do momentu, gdy pokazałem mu je u siebie. 

linux oprogramowanie

Komentarze

0 nowych
nintyfan   11 #1 16.01.2011 18:34

3) Ulepszony globbing

Co do tego, to Bash4 obsługuje identyczną składnię.

nintyfan   11 #2 16.01.2011 18:36

4) Stringi

Tutaj Bash mi przypomina nieco DOS-a, jak również Pythona(tzn. w Pythonie można, jak w C, ale można podobnie do DOS-u, a w samym DOS-ie już nie można podobnie do C). Dodanie możliwości odwołania się do znaku, jak w czystym C niekiedy byłoby pomocne. Zastanawiam się tylko, czy nie dałoby się ustawić znaku pustego w roli separatora.

nintyfan   11 #3 16.01.2011 18:37

@nintyfan | 16.01.2011 18:36 :
Nie da się. Bash automatycznie usuwa znaki puste z ciągów znaków.

nintyfan   11 #4 16.01.2011 18:43

Pewnie CTRL+Q da się skonfigurować w pliku konfiguracyjnym biblioteki readline.

Vifon   5 #5 16.01.2011 19:37

@nintyfan | 16.01.2011 18:34
Bash 4.1.5:
ls: nie ma dostępu do Programs/**/Makefile: No such file or directory

Próbowałem też z 'shopt -s extglob'.

roobal   15 #6 16.01.2011 20:23

Tutaj jest dość ciekawy artykuł na temat Zsh http://jakilinux.org/aplikacje/konsola/zsh-powloka-inna-niz-wszystkie/

Napiszę Ci, że tamten artykuł jakoś nie skłonił mnie nawet do próbnej instalacji ale twój krótki i zwięzły opis mnie do tego zachęcił jak najbardziej, tak więc w ramach testów zainstalowałem sobie Zsh na FreeBSD i powiem szczerze, że ta powłoka przypadła mi do gustu.

Domyślna powłoka FreeBSD, jaką jest Sh normalnie doprowadzała mnie do szału i nawet na tym systemie musiał być Bash.

Na Ubuntu póki co zostanę jeszcze przy Bashu, dopóki bliżej nie zapoznam się z nową powłoką ;)

Pozdrawiam!

borzole   4 #7 17.01.2011 02:38

- proteza na wspólną historię w bash: dopisać do ~/.bashrc
----------
PROMPT_COMMAND='history 1 >> /${HOME}/.bashrc_history.all'
----------
- globbing i stringi działają w bash bardzo dobrze, czego się czepiasz.
@nintyfan
puste znaki to kwestia ustawienia IFS, ustaw na pusty a zachowa formatowanie tekstu:
----------
x=' Hello world '
IFS=
echo $x
----------
- proteza na uzupełnianie poleceń tabem: bash-completion
rzadkich programów nie uzupełni, ale większość obsługuje.

Interaktywna praca wydaje się kusić bardziej pod zsh, ale pisać skrypty wolę pod bash. Ogólnie nie używam terminala do komend dłuższych niż trzy słowa, wolą napisać skrypt (lepsze niż historia poleceń). Dlatego zsh: bye bye :P

Pigmej   5 #8 17.01.2011 04:02

Skoro już przy shellach to polecam fish.

Pracuje mi sie z nim zdecydowanie wygodniej niz z zsh... no i do tego ma chyba jeszcze lepsze uzupelnianie niz zsh ( aptitude install cos[tab] itp ).

A i do tego gotowa do dzialania zaraz po starcie :) Tylko ze projekt cos niestety chyba 'pada'

nintyfan   11 #9 17.01.2011 05:44

@Pigmej | 17.01.2011 4:02 :
Fish jest stworzony dla normalnych użytkowników. W tym sensie, że ma włączone domyślnie opcje, które ZSH ma domyślnie wyłączone, jak choćby otwieranie plików w domyślnie skojarzonym programie.

Pigmej   5 #10 17.01.2011 22:13

generalnie... fish lepiej podpowiada, zsh z tego co wiem nie podpowie ci do komend ktore wyrzucaja swoje na stdout... on umie.

Jaahquubel_   13 #11 17.01.2011 23:15

Bardzo ciekawy wpis.
Punkt 6. i 8. (ten drugi 8. ;) ) mnie zaciekwaiły.
O powłokach nie wiem nic (bo mi nie było potrzeba). Czy można mieć jednocześnie bash-a i zsh?
Czy w zsh mogę sobie tak zrobić, żeby wpisanie np. "gn" i wciśnięcie strzałki w górę powodowało przeszukanie jedynie poleceń zaczynających się od "gn"? Nie pamiętam czy to ustawienie basha, czy globalne.

@borzole
"proteza na wspólną historię w bash: dopisać do ~/.bashrc
PROMPT_COMMAND='history 1 >> /{HOME}/.bashrc_history.all'"
Czemu proteza?
Czy jak to zapodam, to zadziała i na historię poleceń Octave'a? Bo Octave to jedyny program, dla którego taka współdzielona historia jest mi potrzebna (jej brak spowodował mi ostatnio mały poślizg z robotą).

Vifon   5 #12 17.01.2011 23:42

@Jaahquubel_
Nie można mieć uruchomionych naraz dwóch shelli (chyba, że oddzielnie). To tak jakbyś chciał Operę i Chrome'a w jednym.

Wyszukiwanie takie, jak opisałeś można zrobić tak:
bindkey '^[[A' history-beginning-search-backward
^[ to jeden znak - wstawiasz go przez Ctrl+V Escape. Całość możesz wstawić Ctrl+V strzałka_do_góry.

Dzięki za uwagę o numeracji, już poprawiam.

@Pigmej
Fisha próbowałem przez chwilę i wyglądał nawet ciekawie. Niestety ciężko mi było znaleźć jakieś manuale, więc zrezygnowałem. Z zsh też nie jest najlepiej, ale jednak trochę tego jest. I nie wyskakują mi poradniki dla amatorów hodowli ryb. ;)
BTW zsh też uzupełnia pakiety aptitude. Bash również.

  #13 19.12.2011 17:20

Zaczynam zabawę z zsh i nie wiem dlaczego nie chce wyświetlać dopełnień do plików - np. filmów, zdjęć.

  #14 29.10.2013 20:13

8) Przechowywanie poleceń na później <- (tu się nie zgodzę)
w bashu ctrl+u, ctrl+y