:sparkles: PWA :sparkles:
Twarz autora bloga

Piotr Kowalski

Organizator WarsawJS Trener YouTuber

Fish - shell przyjazny każdemu


Powodem dla którego napisałem ten post jest przedstawienie ciekawej powłoki terminala, konkurenta domyślnej bash w taki sposób, aby szybko zacząć korzystanie z niego. Fish to o nim mowa.

Nazwa jest interesująca, jednak tu nie chodzi o jakiekolwiek ryby. Rozwinięciem akronimu jest Friendly Interactive Shell. Przychylam się do tej nazwy. Powłoka jest bardzo elastyczna. Możliwości konfiguracyjne są bardzo duże, jest ona zdecydowanie łatwiejsza w porównaniu z domyślnym bashem - Bourne-Again Shell.

Fish
Oficjalne logo powłoki.

Jak zacząć?

Od kilku lat używam OSXa. Ten artykuł będzie więc pisany z perspektywy programisty korzystającego na co dzień z tego systemu.

Jestem jednak przekonany, że konfiguracja powłoki Fish, wygląda podobnie na wszystkich systemach Unixowych. Kilka lat temu moim podstawowym systemem był Linux, na którym też skonfigurowałem Fisha.

Najprzyjemniejsza instalacja pakietów zawsze będzie zorientowana na wykorzystaniu managera pakietów. Jeśli chodzi o system OSX to nie ma takiego managera w domyślnej instalacji. Ze swojej strony polecam instalację Homebrew. Bardzo prosty i wolny od błędów, przynajmniej podczas mojego kilkuletniego doświadczenia.

Instalacja

Proces instalacji skupia się na wydaniu w terminalu takiego polecenia:

brew install fish

Po samej instalacji możemy przełączyć się na nową powłokę wykonując polecenie fish. Jednak idźmy krok dalej. Skonfigurujmy środowisko tak, aby zmienić domyślną powłokę. Aby uniknąć błędu:

ERROR: /usr/local/bin/fish: non-standard shell

należy w pliku /etc/shells, w którym znajduje się lista ze wspieranymi shellami, dodać nowy rekord ze ścieżką do Fisha. Edytujemy plik poleceniem:

vim /etc/shells

oraz dodajemy taką linijkę:

...
/usr/local/bin/fish
...
Skąd wiem jaka jest ścieżka do pliku binarnego?
Nie wiem, ale wydając polecenie which fish dostaniemy ścieżkę do pliku fish.

Zamiana domyślnego shella

Do zmiany domyślnej powłoki dla obecnie zalogowanego użytkownika, korzystamy z polecenia:

chsh -s `which fish`

Parametr -s wymaga wskazania ścieżki do shella, uzyskujemy go dodając polecenie which fish otaczając je znakami backtick.

Konfiguracja powłoki Fish

Każdy shell posiada możliwość konfiguracji "pod siebie", czyli tak, aby praca w nim była przyjemnością, a nie udręką. Na przykład tworzenie aliasów skraca czas wpisywania tych samych komend. Główny plik konfiguracyjny dla powłoki Fish znajduje się w pliku:

vim ~/.config/fish/config.fish

Jeśli taki plik nie istnieje, to nie ma problemu, abyśmy go stworzyli. Uzupełnijmy konfigurację o podstawowy edytor powłoki. Oczywiście będzie nim Vim.
W pliku config.fish wpisujemy poniższą linijkę:

set -U EDITOR vim

Tworzy ona uniwersalną zmienną $EDITOR. Po restarcie powłoki, pod zmienną środowiskową $EDITOR będzie znajdował się edytor Vim. Dlaczego to jest takie ważne? Wiele narzędzi korzysta z tej zmiennej, aby użyć edytora podczas swoich prac, np. polecenie git commit korzysta z domyślnego edytora, aby zaprezentować developerowi zmiany w projekcie (jeśli takie istnieją).

Bardzo prosty przykład pliku konfiguracyjnego ~/.config/fish/config.fish

# Setup default editor
set -u editor vim

# Disable default greeting message
set fish_greeting

# Load private aliases
source ~/.aliases

Vim na Fishu?

Aby uniknąć błędu:

syntastic: error: your shell /usr/local/bin/fish can't handle traditional UNIX syntax for redirections

Trzeba do konfiguracji Vima, czyli w pliku .vimrc ustawić domyślną powłokę

set shell=bash

Więcej o błędzie można przeczytać w tym issue.

Pytania i odpowiedzi

Jakie są zalety?
Zalet jest dużo. Największe zalety to: duża społeczność, autosugestie, proste skrypty z konfiguracją, podpowiadanie mana.
Jakiego języka trzeba używać pisząc skrypty dla Fisha?
Pisząc skrypty będziemy używali shella według składni Posix.
Gdzie jest miejsce na trzymanie konfiguracji powłoki?
Plik ze wszelką konfiguracją związaną z Fishem znajduje się w katalog ~/.config/fish/. Główny plik konfiguracyjny jest w tym katalogu pod nazwą config.fish.
Jakie rozszerzenie jest wymagane, aby skrypt był brany pod uwagę przez powłokę Fish?
Nie ma żadnego wymaganego rozszerzenia. Można w katalogu ~/.config/fish/functions/ tworzyć pliki z dowolnym rozszerzeniem, a nawet bez niego.
Czy nazwa pliku w katalogu ~/.config/fish/functions/ ma znaczenie?
Tak. Nazwa pliku musi odpowiadać funkcji, która zostanie dodana to środowiska i będzie dostapna jako polecenie. Rozszerzenie nie jest ważne.
Czy można w konfiguracji config.fish definiować funkcje?
Nie. Tam definiuje się tylko pojedyncze ustawienia - każde w innej linii. Funkcje definiujemy w katalogu ~/.config/fish/functions/.
Jak zmienić domyślny prompt?
Wystarczy stworzyć plik ~/.config/fish/fish_prompt.fish i stworzyć w nim funkcję o nazwie fish_prompt. Przykład:
function fish_prompt
    echo ' > '
end
Co to jest fish_right_prompt?
prompt jest to tzw. znak zachęty. Znajduje się on zawsze po lewej stronie. Od tej wartości zaczyna się linia w której na końcu mam ustawiony kursor, gdzie możemy coś wpisać. Jednak co jeśli chcielibyśmy wpisać coś po prawej stronie? Mamy możliwość poprzez funkcję:
function fish_right_prompt
    echo (date '+%H:%M:%S)
end

Jak to będzie wyglądało w praktyce? Poniżej przykład.

Powyższa funkcja w praktyce.

Więcej detali można znaleźć w oficjalnej dokumentacji.

Ciekawostki

Design

Rzadko kiedy spotyka się tak dobrze zapisane zasady projektu, jak ma to miejsce w przypadku Fisha. Pełna lista praw i zasad dostępna jest tutaj. W dokumencie znajduje się lista następujących praw: "The law of orthogonality", "The law of responsiveness", "The law of user focus" oraz "The law of discoverability".

Bardzo ciekawym prawem jest zasada, że jeśli wystąpi sytuacja, że 2 rozwiązania jest zaimplementowane podobnie, ale nie są identyczne, to jedno z nich trzeba usunąć a to drugie ulepszyć. Taka zasada powinna panować w każdym managerze paczek, np. w npm. Tylko kto by weryfikował każdą paczkę?

Kolejne ciekawe prawo mówi, żeby doprowadzić do sytuacji, aby w jak najkrótszym czasie nowy użytkownik stał się ekspertem w danym narzędziu. Jest to oznaką zaprojektowania szybkiego wykrywania / odnajdywania nowych opcji programu. Każda funkcja powinna posiadać komentarz, aby była bardziej zrozumiała, jeszcze przed użyciem.

Zdarzenia

Bardzo ciekawe jest to, że powłoka umożliwia nam nasłuchiwania na zdarzeniach. Pierwszy raz spotykam się z taką możliwości, że np. jedno polecenie / narzędzie emituje zdarzenie, a inne nasłuchuje na nie i się uruchamia.

Więcej w tym temacie jest dostępne tutaj.

Mój sposób na dotfiles

W dzisiejszych czasach, developerzy mają swoje serwery np. na hosting, vps-y. Tam też chcielibyśmy mieć fish shella. Jak przenieść całą konfigurację na serwer?

Pomysłem jest stworzenie projektu dotfiles z naszą konfiguracją środowiska pracy. Wystarczy na serwerze (miejscu docelowym) pobrać repozytorium i rozpropagować konfigurację w odpowiednie miejsce.

Ze względu na liczbę konfiguracji środowiska większą niż 1 plik, warto skorzystać z narzędzia rsync, które zadba od skopiowanie / nadpisanie plików z projektu dotfiles w zdefiniowane przez nas miejsce. Osobiście używam takiego polecenia do instalacji konfiguracji powłoki Fish:

rsync -rv ~/projects/dotfiles/.config/fish/* ~/.config/fish/

Ze względu na tak długie polecenie polecam stworzyć sobie skrypt shellowy, w którym wyżej wymieniona linijka znajdzie swoje miejsce. Dzięki takiemu skryptowi będzie możliwość dodania jeszcze innych konfiguracji, np. Vima, Gita.

Źródła warte przeczytania

Dobra wiadomość dla użytkowników Windowsa
Dostępna jest opcja FISHa z Cygwinem!