Obsah
1. Nástroj Go Bullet Train (GBT)
2. Moderní shelly a proměnné prostředí PS1 až PS4
3. Základní funkce nástroje GBT
4. Instalace fontu DejaVu Sans Mono Nerd
8. Délka cesty k aktuálnímu adresáři
9. Specifikace, které informace se mají zobrazit
10. Barva popředí a pozadí jednotlivých „vagonů“
11. Volba ikony představující aktuálně používanou distribuci nebo prostředí
12. Vagony používané v naklonovaném GIT repositáři
13. Ikona s informací o skrytých změnách (stash)
14. Informace o virtuálním prostředí Pythonu
16. Obsah následující části seriálu
1. Nástroj Go Bullet Train (GBT)
K unixovým systémům, mezi které patří i Linux, neodmyslitelně patří i příkazová řádka zajišťující vstup uživatelem zapisovaných příkazů určených pro shell. Vlastnosti příkazové řádky v prvních interpretrech byly z dnešního pohledu dosti omezené, což platí zejména pro původní Bourne shell, ovšem postupně došlo k vylepšování jejich možností. Například v Korn shellu se objevila možnost editace příkazové řádky, a to buď v režimu Emacsu či Vimu (což je vlastnost, která je podporovaná dodnes), v C shellu historie příkazů, podpora aliasů atd. Pravděpodobně nejvíce možností v současnosti nabízí FISH, kterým se později budeme v tomto seriálu zabývat. Existuje taktéž poměrně velké množství nástrojů, které dokáží vylepšit vlastnosti příkazové řádky v dnes běžných shellech (BASH, DASH, ZSH atd.). Jedním z těchto užitečných nástrojů je i Go Bullet Train neboli zkráceně GBT, jemuž je věnován dnešní článek.

Obrázek 1: Nástroj Go Bullet Train dokáže detekovat aktuálně používanou distribuci a při korektním nastavení zobrazit její logo. Zde je ukázáno, že se logo změní při nalogování na počítač s odlišnou distribucí, zde konkrétně z distribuce založené na Ubuntu (Linux Mint) na Fedoru. Tato funkcionalita však vyžaduje instalaci speciálního fontu.
2. Moderní shelly a proměnné prostředí PS1 až PS4
Nástroj Go Bullet Train dokáže změnit informace zobrazované v rámci takzvané „výzvy“ (prompt). V „klasických“ shellech se obsah výzvy nastavuje s využitím proměnné prostředí PS1, popř. dalších proměnných PS2 až PS4 použitých ve specifických případech (PS2 pro víceřádkové příkazy, PS3 při čekání na vstup uživatele v interaktivních skriptech, PS4 v ladicím režimu). Tyto proměnné prostředí mohou obsahovat jak běžný text (typicky znak $), tak i speciální znaky začínající zpětným lomítkem. Tyto znaky jsou při konstrukci zprávy představující výzvu nahrazeny jinou hodnotou zjištěnou z prostředí, v rámci něhož je shell spuštěn. Například znak \u je nahrazen jménem uživatele, znak \w je expandován na právě používaný adresář (current working directory), znak \A je expandován na čas atd. Navíc je možné používat i různé řídicí znaky, které mohou modifikovat barvu textu, barvu pozadí, styl textu (podtržení, tučné písmo/vysvícení atd.). Tyto znaky lze zapisovat přímo nebo je možné využít výstup z příkazu tput. Jedná se o velmi užitečnou funkcionalitu a dokonce existuje i interaktivní nástroj, kterým je možné proměnnou prostředí PS1 až PS4 nastavit – viz též https://www.kirsle.net/wizards/ps1.html.

Obrázek 2: Vytvoření obsahu proměnné PS1 v interaktivním editoru dostupném na adrese https://www.kirsle.net/wizards/ps1.html.
3. Základní funkce nástroje GBT
Základní funkcí nástroje Go Bullet Train je modifikace výzvy (prompt), ovšem poněkud odlišným způsobem, než přímou ruční editací obsahu proměnné prostředí PS1. Práce s proměnnou prostředí PS1 je totiž relativně složitá, a to mj. i z toho důvodu, že se do jediného řetězce musí zapisovat vzájemně nesouvisející údaje, pro některé složitější operace se volají funkce naprogramované například přímo v shellu, znaky pro expanzi se kombinují s běžnými znaky i znaky řídicími (terminálové sekvence) atd. Naproti tomu při použití GBT je samotná výzva rozdělena do několika částí, které se nastavují automaticky (jednotlivé části výzvy se za sebou skutečně vizuálně napojují jako vagony v rychlovlacích). Navíc GBT podporuje zobrazování ikon (to ovšem vyžaduje použití speciálně upraveného fontu), relativně snadnou změnu barev popředí i pozadí textu, dobrou kooperaci s gitem (zjišťování stavu lokálně naklonovaného repositáře), stejnou výzvu lze použít i na vzdálených strojích (přes SSH) atd. A nesmíme zapomenout ani na to, že díky tomu, že nástroj GBT je vyvinut v programovacím jazyce Go, je jeho instalace snadná až triviální (jedná se o jediný spustitelný soubor).

Obrázek 3: Uživatel je nalogován jako Root do operačního systému RHEL.
4. Instalace fontu DejaVu Sans Mono Nerd
Jak jsme si již řekli v předchozí kapitole, umožňuje Go Bullet Train zobrazení některých informací (stav repositáře, aktuálně používaná distribuce, výsledek posledního spuštěného příkazu) ve formě ikon. Ovšem tyto ikony je nutné nějakým způsobem zobrazit v „pouhém“ textovém terminálu. Jak toho dosáhnout? Prakticky všechny moderní terminály podporují použití Unicode fontů, v nichž je na určitých místech umístěna příslušná ikona. Tu nakonec stačí pouze obarvit (volba barvy popředí popř. pozadí) s využitím terminálových sekvencí. GBT používá ikony, které nalezneme ve fontu DejaVu Sans Mono Nerd, který je nutné nainstalovat, což je velmi ve skutečnosti snadné a nebudeme k tomu potřebovat ani práva roota.
Nejdříve je nutné vytvořit adresář .fonts umístěný v domácím adresáři (pokud tento adresář existuje, ponecháme jeho obsah nezměněný):
$ mkdir -p ~/.fonts
Následně stáhneme příslušný font (DejaVu Sans Mono Nerd) ve formátu TrueType a uložíme ho do adresáře .fonts v domácím adresáři:
$ curl -L -o ~/.fonts/DejaVuSansMonoNerdFontCompleteMono.ttf https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/DejaVuSansMono/Regular/complete/DejaVu%20Sans%20Mono%20Nerd%20Font%20Complete%20Mono.ttf
Poslední krok spočívá v novém vytvoření souborů s informacemi o fontech, které mohou aplikace použít. Pro tento účel postačuje spustit příkaz fc-cache (bez dalších parametrů):
$ fc-cache
Aktuálně dostupné fonty je možné vypsat nástrojem fc-list. Například všechny fonty, v jejichž názvu se vyskytuje slovo „Nerd“ vypíšeme následujícím způsobem:
$ fc-list | grep Nerd /home/tester/.fonts/DejaVuSansMonoNerdFontCompleteMono.ttf: DejaVuSansMono Nerd Font Mono:style=Book
Jen pro zajímavost si můžeme vypsat podrobnější informace o právě nainstalovaném fontu:
$ fc-query /home/tester/.fonts/DejaVuSansMonoNerdFontCompleteMono.ttf Pattern has 23 elts (size 32) family: "DejaVuSansMono Nerd Font Mono"(s) familylang: "en"(s) style: "Book"(s) stylelang: "en"(s) fullname: "DejaVu Sans Mono Nerd Font Complete Mono"(s) fullnamelang: "en"(s) slant: 0(i)(s) weight: 80(i)(s) width: 100(i)(s) spacing: 100(i)(s) foundry: "unknown"(s) file: "/home/tester/.fonts/DejaVuSansMonoNerdFontCompleteMono.ttf"(s) index: 0(i)(s) outline: True(s) scalable: True(s) ... ... ... lang: aa|af|ar|ast|av|ay|az-az|az-ir|bm|be|bg|bi|bin|br|bs|bua|ca|ce|ch|chm|co|cs|cv|cy|da|de|el|en|eo|es|et|eu|fa|fi|fj|fo|fr|ff|fur|fy|ga|gd|gl|gn|gv|ha|haw|ho|hr|hu|hy|ia|ig|id|ie|ik|io|is|it|ka|kaa|ki|kk|kl|ku-am|kum|kv|kw|ky|la|lb|lez|ln|lt|lv|mg|mh|mi|mk|mo|mt|nb|nds|nl|nn|no|nr|nso|ny|oc|om|os|pl|pt|rm|ro|ru|sah|sco|se|sel|shs|sk|sl|sm|sma|smj|smn|so|sq|sr|ss|st|sv|sw|tk|tl|tn|to|tr|ts|tt|tw|tyv|uk|uz|ve|vo|vot|wa|wen|wo|xh|yap|yo|zu|ak|an|ber-dz|crh|csb|ee|fat|fil|hsb|ht|hz|jv|kab|kj|kr|ku-tr|kwm|lg|li|mn-mn|ms|na|ng|nv|pap-an|pap-aw|qu|quz|rn|rw|sc|sg|sn|su|ty|za(s) fontversion: 155320(i)(s) capability: "otlayout:DFLT otlayout:arab otlayout:cyrl otlayout:grek otlayout:lao otlayout:latn"(s) fontformat: "TrueType"(s) decorative: False(s) hash: "sha256:3d7584de56eebaed3262ec71670083aeb9fcb8ce0c8b6c3e2487f2aeb54660c7"(s) postscriptname: "DejaVuSansMonoNerdFontCompleteM-Book"(s)
5. Konfigurace terminálu
V dalším kroku je nutné nakonfigurovat terminál. Budeme potřebovat nastavit minimálně dvě základní vlastnosti:
- Použitý font by měl být „DejaVuSansMono Nerd Font Mono“ nainstalovaný v rámci předchozí kapitoly
- Barva pozadí by měla být tmavá (většina nastavení GBT totiž na světlém pozadí špatně pracuje)
U terminálů (přesněji řečeno emulátorů terminálu), které jsou vybaveny grafickým uživatelským rozhraním s menu se toto nastavení provede přímo z tohoto menu, typicky výběrem položky Settings. Poněkud složitější je situace v případě použití terminálů urxvt a xterm. Podívejme se na nastavení xtermu, které lze provést i bez toho, abychom zasahovali do databáze xrdb (X server resource database):
$ xterm -bg black -fg white -en en_US.UTF-8 -u8 -fa "DejaVuSansMono Nerd Font Mono" -fs 20
Výše uvedený příkaz používá přepínač -bg pro nastavení barvy pozadí, -fg pro nastavení barvy popředí, -fa pro volbu fontu (nikoli bitmapového), -fs pro změnu velikosti písma a nakonec -u8 a -en pro povolení Unicode.

Obrázek 4: V případě, že je návratová hodnota posledního příkazu odlišná od nuly, je ve výchozím nastavení GBT tato skutečnost naznačena červeným křížkem na začátku výzvy.
6. Instalace nástroje GBT
Instalaci nástroje Go Bullet Train je možné provést několika způsoby. Využít je možné balíčky dostupné na adrese https://packagecloud.io/gbt/release, které jsou nabízeny ve formátech .deb i .rpm pro různé architektury. Alternativně je možné nástroj GBT přeložit, k čemuž je pouze zapotřebí mít nainstalovány základní nástroje programovacího jazyka Go a nastaveny proměnné prostředí GOPATH a PATH (jinak nebude GBT instalovatelný a spustitelný):
$ export GOPATH=~/go $ export PATH="$PATH:$GOPATH/bin"
Samotnou instalaci GBT zajistí příkaz go get, který stáhne potřebné knihovny a následně provede překlad a slinkování výsledné utility:
$ go get github.com/jtyr/gbt/cmd/gbt
Výsledkem předchozího příkazu by měl být spustitelný soubor se jménem „gbt“ umístěný v adresáři „~/go/bin“:
$ ls -l $GOPATH/bin total 14184 -rwxr-xr-x 1 tester tester 3002684 lis 29 19:02 gbt -rwxr-xr-x 1 tester tester 11515559 lis 10 21:56 gocode
Následně je nutné určit, že obsah proměnné PS1 bude určen právě příkazem GBT, což je již triviální operace:
$ PS1='$(gbt $?)'
V případě ZSH se nastavuje proměnná prostředí PROMPT a nikoli PS1:
$ PROMPT='$(gbt $?)'
V případě, že používáte ZSH, je možné nastavit i „pravou“ výzvu, což je měnitelný text zobrazený na pravém okraji příkazového řádku:
$ RPROMPT='$(gbt -right)'
Ihned po spuštění by se měl změnit formát výzvy (promptu) v aktuálně spuštěném emulátoru terminálu.

Obrázek 5: Nastavení tří „vagónů“, z nichž se skládá konfigurace výzvy (prompt).
7. Konfigurace nástroje GBT
Konfigurace nástroje Go Bullet Train se provádí s využitím proměnných prostředí. Ty lze nastavovat interaktivně (změny jsou ihned zapracovány a modifikují chování GBT), nebo je možné nastavení provést například v souborech .profile, .bashrc atd.

Obrázek 6: Ukázka situace, kdy je cesta k aktuálnímu adresáři poměrně dlouhá.
8. Délka cesty k aktuálnímu adresáři
První nastavení se týká cesty k aktuálnímu adresáři. V některých případech (domácí adresář, kořenový adresář) je tato cesta velmi krátká, ovšem mnohdy se pohybujeme v tak košaté struktuře, že cesta k aktuálnímu adresáři může překračovat šířku terminálu. K omezení počtu zobrazených podadresářů slouží proměnná prostředí GBT_CAR_DIR_DEPTH. Pokud je hodnotou této proměnné například řetězec „3“, budou zobrazeny jen poslední tři podadresáře cesty:
$ export GBT_CAR_DIR_DEPTH='3'
nebo jen:
$ export GBT_CAR_DIR_DEPTH=3
Ve chvíli, kdy naopak použijeme například řetězec „999“, je délka zobrazené cesty prakticky neomezená:
$ export GBT_CAR_DIR_DEPTH=999
9. Specifikace, které informace se mají zobrazit
Název projektu Go Bullet Train vychází z toho, že se zprávy, z nichž je skládána výzva (prompt) vytváří z jednotlivých „vagonů“, které jsou nezávisle na sobě konfigurovatelné a spojitelné do jediného „vlaku“. A právě k určení, které „vagony“ a v jakém pořadí se mají ve výzvě použít, slouží proměnná prostředí nazvaná GBT_CARS. Do této proměnné se zapisuje řetězec se seznamem názvů jednotlivých vagonů, například:
$ GBT_CARS='Status, Os, Time, Hostname, Dir, Git, Sign'
K dispozici je několik typů „vagonů“:
# | Jméno vagonu | Předpona proměnných prostředí |
---|---|---|
1 | Custom car | GBT_CAR_CUSTOM_ |
2 | Dir car | GBT_CAR_DIR_ |
3 | ExecTime car | GBT_CAR_EXECTIME_ |
4 | Git car | GBT_CAR_GIT_ |
5 | Hostname car | GBT_CAR_HOSTNAME_ |
6 | Kubectl car | GBT_CAR_KUBECTL_ |
7 | Os car | GBT_CAR_OS_ |
8 | PyVirtEnv car | GBT_CAR_PYVIRTENV_ |
9 | Sign car | GBT_CAR_SIGN_ |
10 | Status car | GBT_CAR_STATUS_ |
11 | Time car | GBT_CAR_TIME_ |
S vybranými vagony se seznámíme v navazujících kapitolách.

Obrázek 7: Nastavení, které informace se mají ve výzvě zobrazit.
10. Barva popředí a pozadí jednotlivých „vagonů“
U jednotlivých vagonů lze zvolit jejich barvu popředí a pozadí. K tomu slouží proměnné prostředí začínající předponou vypsanou v tabulce v předchozí kapitole a končící na _BG (barva pozadí, background) či _FG (barva popředí, foreground). Dále je možné proměnnou prostředí končící na _FM určit styl písma (tučné atd.). Podívejme se na příklad, v němž nastavíme pozadí vagonu zobrazujícího stav posledního provedeného příkazu (návratový kód je roven nule či odlišný od nuly):
$ export GBT_CAR_STATUS_DISPLAY=1 $ export GBT_CAR_STATUS_OK_BG=green $ export GBT_CAR_STATUS_ERROR_BG=green

Obrázek 8: Změna barvy popředí a pozadí vybraných „vagonů“
Pro popředí popř. pozadí lze zvolit následující barvy:
# | Barva |
---|---|
1 | black |
2 | red |
3 | green |
4 | yellow |
5 | blue |
6 | magenta |
7 | cyan |
8 | light_gray |
9 | dark_gray |
10 | light_red |
11 | light_green |
12 | light_yellow |
13 | light_blue |
14 | light_magenta |
15 | light_cyan |
16 | white white |
11. Volba ikony představující aktuálně používanou distribuci nebo prostředí
V případě, že je nainstalován font „DejaVu Sans Mono Nerd“, je možné proměnnou prostředí GBT_CAR_OS_NAME zvolit, jaká ikona distribuce popř. prostředí se má zobrazit ve vagonu „Os“. Některé příklady jsou ukázány na následujícím screenshotu:

Obrázek 9: Volba ikony představující aktuálně používanou distribuci nebo prostředí.
Ikony, které je možné použít (sami můžete vidět, že ne vždy se jedná pouze o názvy distribucí Linuxu):
amzn | cloud | elementary | linuxmint | redhat |
android | coreos | fedora | mageia | sabayon |
arch | darwin | freebsd | mandriva | slackware |
archarm | debian | gentoo | opensuse | ubuntu |
centos | docker | linux | raspbian | windows |
12. Vagony používané v naklonovaném GIT repositáři
Ve chvíli, kdy aktuální adresář leží v naklonovaném GIT repositáři, je možné zobrazit informace o aktuálním stavu tohoto repositáře, tj. například používanou větev, stav větve (počet souborů, které je možné zařadit do změn) atd. K tomuto účelu slouží vagon „git“ konfigurovatelný s využitím proměnných prostředí, které všechny – podle očekávání – začínají na GBT_CAR_GIT_. Kromě již popsaných proměnných určujících barvu popředí, barvu pozadí a typ písma je důležitá především proměnná GBT_CAR_GIT_FORMAT určující, jaké informace a v jakém formátu se vlastně mají zobrazit.
Zobrazení ikony s informací, že se jedná o GIT repositář:
$ GBT_CAR_GIT_FORMAT='{{ Icon }}'
Přidání jména větve, tagu, commitu:
$ GBT_CAR_GIT_FORMAT='{{ Icon }} {{ Head }}'
Přidání ikony informující o stavu repositáře (synchronizován atd.):
$ GBT_CAR_GIT_FORMAT=' {{ Icon }} {{ Head }} {{ Status }}'
Další ikony popř. text s informací o tom, jaký je stav repositáře v porovnání se vzdáleným repositářem (typicky origin):
$ GBT_CAR_GIT_FORMAT=' {{ Icon }} {{ Head }} {{ Status }} {{ Ahead }} {{ Behind }} '
Mezery ve specifikaci formátu mají význam, takže pokud šetříte místem, lze napsat:
$ GBT_CAR_GIT_FORMAT='{{ Icon }}{{ Head }}{{ Status }}{{ Ahead }}{{ Behind }} '

Obrázek 10: Nastavení barvy pozadí vagonu s informacemi o GIT repositáři.

Obrázek 11: Vytvoření nové větve s přepnutím do této větve. Následně se do repositáře zařadí nový soubor.

Obrázek 12: Smazání nepoužité větve.
13. Ikona s informací o skrytých změnách (stash)
Užitečná je i informace o tom, že naklonovaný repositář obsahuje změny, které byly skryty příkazem stash. Tuto ikonu do výzvy přidáte snadno:
$ GBT_CAR_GIT_FORMAT='{{ Icon }}{{ Head }}{{ Status }}{{ Stash }} '
Výsledek je patrný na dalším screenshotu:

Obrázek 13: Použití ikony „stash“ informující (pokud je zobrazena)

Obrázek 14: Konfigurace zobrazení informací o stavu GITového repositáře, v němž se nachází aktuální adresář.
14. Informace o virtuálním prostředí Pythonu
Zobrazit je možné i informace o aktivovaném virtuálním prostředí Pythonu. Nejdříve je ovšem nutné zakázat, aby samotné virtuální prostředí Pythonu (virtualenv) po své aktivaci příkazem activate do výzvy přidávalo další informace. To se provede nastavením následující proměnné prostředí:
$ export VIRTUAL_ENV_DISABLE_PROMPT='1'
Následně lze nastavit formát vagonu s informacemi o virtuálním prostředí:
$ export GBT_CAR_PYVIRTENV_FORMAT=' {{ Icon }} {{ Name }}
Vagon je nutné přidat do vlaku:
$ export GBT_CARS="Status, Os, Dir, PyVirtEnv"
Nyní je již možné prostředí aktivovat, což by se mělo projevit na zprávě výzvy:
$ source bin/activate
16. Vagon „custom“
K dispozici je i vagon nazvaný jednoduše „custom“, který může zobrazovat buď statický text, nebo výsledek nějakého příkazu. Povolení použití tohoto vagonu:
$ export GBT_CARS="Custom, Status, Os, Dir, PyVirtEnv" $ export GBT_CAR_CUSTOM_DISPLAY=1
Zobrazení statického textu:
$ export GBT_CAR_CUSTOM_TEXT_TEXT=">"
Zobrazení výsledku prakticky libovolného příkazu namísto statického textu:
$ unset GBT_CAR_CUSTOM_TEXT_TEXT
Zobrazení volné kapacity paměti:
$ export GBT_CAR_CUSTOM_TEXT_CMD="cat /proc/meminfo | sed -n 2p | grep -o '[0-9]\+'"
Popř. přesnější příkaz, pokud se pořadí položek ve virtuálním souboru /proc/meminfo mění:
$ export GBT_CAR_CUSTOM_TEXT_CMD="cat /proc/meminfo | grep 'MemFree:' | grep -o '[0-9]\+'"
16. Obsah následující části seriálu
V navazující části právě vznikajícího seriálu o vylepšení vlastností příkazové řádky si popíšeme nástroj bat. Jedná se o utilitu doplňující vlastnosti standardního nástroje cat o mnoho dalších užitečných funkcí, zejména o zvýraznění zdrojových kódů. Tuto utilitu, která je mimochodem naprogramovaná v Rustu, lze použít společně s dalším velmi užitečným nástrojem fzv, jemuž bude věnována celá třetí část seriálu (fzv neboli command-line fuzzy finder navíc lze velmi dobře zkombinovat například s textovým editorem Vim).
17. Odkazy na Internetu
- Go Bullet Train (GBT)
https://github.com/tisnik/gbt - bullettrain-sh
https://github.com/caiogondim/bullet-train.zsh - An oh-my-zsh shell theme based on the Powerline Vim plugin
https://github.com/caiogondim/bullet-train.zsh - Nerd fonts
https://www.nerdfonts.com/ - nerd-fonts (repositář)
https://github.com/ryanoasis/nerd-fonts - Repositář projektu bat
https://github.com/sharkdp/bat - bat releases
https://github.com/sharkdp/bat/releases - Shell
https://en.wikipedia.org/wiki/Shell_(computing) - Minimalistická a rychlá příkazová řádka pro libovolný shell Starship
https://www.root.cz/zpravicky/minimalisticka-a-rychla-prikazova-radka-pro-libovolny-shell-starship/ - Finally, a command line shell for the 90s
http://fishshell.com/ - Bourne shell
https://en.wikipedia.org/wiki/Bourne_shell - Korn shell
http://www.kornshell.org/ - Prompt Expansion
http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html#Prompt-Expansion - PS1 prompt explained for Linux/Unix
https://www.linuxnix.com/linuxunix-shell-ps1-prompt-explained-in-detail/ - Bash $PS1 Generator2.0
https://www.kirsle.net/wizards/ps1.html - BASH Git Prompt
https://github.com/magicmonty/bash-git-prompt - Seznam vybraných Unicode fontů
https://en.wikipedia.org/wiki/Unicode_font#List_of_Unicode_fonts - Unix History
https://www.levenez.com/unix/ - C shell
https://en.wikipedia.org/wiki/C_shell - tput(1) – Linux man page
https://linux.die.net/man/1/tput - fc-list(1) – Linux man page
https://linux.die.net/man/1/fc-list - fc-cache(1) – Linux man page
https://linux.die.net/man/1/fc-cache - fc-query(1) – Linux man page
https://linux.die.net/man/1/fc-query - Unicode character recognition
http://shapecatcher.com/