BASH, ZSH, FISH. A čo takto Eshell?

10.01 | 14:05 | Richard | Richard

V súčasnosti sa používateľ GNU/Linuxu zaobíde aj bez emulátora terminálu. Drvivú väčšinu nastavení, pri zvolení vhodnej distribúcie, spraví cez grafické rozhranie.
Ale kto sa zžil s príkazovým riadkom, na jeho efektivitu, priamočiarosť a rýchlosť nedá dopustiť.

Od BASH-u k eshell-u

Ako asi väčšina, i ja som začínal so shellom (t.j. programom, ktorý je pracovným rozhraním v prostredí príkazového riadku) s názvom bash. A používal som ho dlhé roky. Následne som pod vplyvom videí na YT skúsil zsh a fish. Tie mali niekoľko výborných vlastností, ktoré boli návykové, najmä dopĺňanie prepínačov známych príkazov.

Lenže neskôr som začal intenzívne používať GNU Emacs. To znamená, že som ním nahradil súborový manažér, textový procesor, RSS čítačku, či prehliadač dokumentácie k programovacím jazykom. Ale nielen to. Nahradil mi audio a rádio prehrávače, samozrejme programátorské IDE atď.

A nahradil mi aj bash/zsh/fish shell.

 

Pár motivačných vlastností

Eshell je napísaný v eLisp-e. Snaží sa napodobniť správanie bash-u a príkazov z GNU Coreutils. Je dostupný v Emacse na všetkých podporovaných OS, a (podľa ostatných, ja som to nikdy neskúšal) je lepší ako Cygwin Bash.

 

Ale to je asi primálo, aby to bolo niečim výnimočným, alebo…?

Treba si uvedomiť, že:

V ďalších kapitolách si povieme o jeho príjemných vlastnostiach ešte viac, trochu si ho vylepšíme a spravíme si z neho aj drop-down (a.k.a. Quake) terminál.

 

Základné vlastnosti a iné príjemnosti

Multipass (multishell)

Takže ako bolo spomínané, aj bez dodatočných programov je možné mať viacero shelov vedľa seba. Ak použijeme príkaz man, tak ten sa otvorí v ďalšom okne, pričom focus ostane na pôvodnom. Potom si môžeme (napr. pomocou M-PgDn, M-PgUp) listovať nápovedu a súčasne písať do príkazového riadku. Alebo - skočiť do druhého okna (označenie v Emacse je trochu zmätočné - okno - window je de-facto rozdelené aktuálne okno Emacsu na viaceré a rámec - frame je osobitné, oddelené okno [viac z histórie tu]) a odtiaľ si (aj bez myši) prekopírovať text do schránky (v Emacsi je nazývaná kill-ring).
Či je to už okno alebo rámec, všetky tieto entity sú navzájom prepojené.


Obr. 1: Tri shelly v jednom okne Emacs-u

 

Eshell je buffer

A teraz tá úžasná vec - keďže aj eshell je de-facto bežný textový buffer, tak je možné kurzorom behať všetkými smermi. A text označovať, kopírovať či mazať, alebo aj znovu spúšťať príkazy.


Obr. 2: Machrujeme s kurzorom - pohybujeme sa po celom bufferi a kopírujeme text

Takže žiadne pager-y ako more či less nie sú potrebné. A toto je podľa mňa veľmi návykové. Plus možnosť vyhľadávania, zvýrazňovania pomocou regulárnych výrazov, proste všetko, čo si človek môže priať a pokiaľ mu siaha fantázia.

 

Presmerovanie do iného buffera

Na presmerovanie existujú tieto (neviem ako sa to volá):

Takže cieľom môže byť súbor, alebo buffer:

echo "hello world" > #<buffer pozdrav>

Dobré, nie? Nejaký dlhý listing si pozrieť napr. v dočasnom <*scratch*> bufferi.

Eshell má navyše aj tieto pseudozariadenia:

(kill-ring i normálny clipboard môžu spravovať ten istý obsah).

 

ELisp rocks!

Volanie eLispových funkcií umožňuje z príkazového riadku spraviť akýkoľvek úkon, ktorý Emacs dokáže. Takže napríklad:

find-file-other-window <súbor>

Otvorí súbor v novom okne.

Ale nielen to. Takto sa dajú volať ľubovoľné príkazy, aj tie, ktoré sa volajú pomocou M-x, modifikovať premenné Emacsu, definovať funkcie - a to všetko zo spomínaného shellu.

 

Spolupráca s Dired-om

Ako som raz písal v jednom príspevku, Dired je vstavaný nástroj na dávkovú vizuálnu prácu so súbormi. Takže ak narýchlo potrebujeme spraviť hromadné premenovanie, nejaké šikovné makro, komplikovanejšie kopírovanie, príkaz dired . je okamžite poruke.

 

Ďalšie vstavané funkcie

… na ktoré som si navykol a bežne ich používam (uvádzam len názov funkcie, nakoľko priradenie klávesovej skratky je, ako všetko v Emacse, nastaviteľné).

príkazakcia
eshell-next(previous)-prompt

presun v bufferi na nasledujúce (predchádzajúce) zadanie v príkazovom riadku

(defacto nie je potrebné sa presúvať pohybom kurzora na spustený príkaz cez všetky výpisy vykonaného príkazu)

pcomplete-expand

autodoplnenie príkazu či parametra

(ale ukážeme si aj masívnejšie rozšírenie tejto funkcionality)

eshell-show-outputskočí na začiatok výstupu posledného príkazu, čo nám ušetrí skrolovanie pri viac-stránkovom výpise
eshell-next(previous)-matching-input-from-input

doplní ďalší (predchádzajúci) zhodný vstup

(napr. po zadaní cd a zavolaní funkcie je možné listovať medzi zadanými cd v minulosti

eshell-next(previous)-input

klasické listovanie v histórii, ako poznáme z bashu (šípkami ↑ ↓)

 

Vizuálne (ncurses) programy

Ako bolo spomínané, eshell si nepodarí s celoobrazovkými TUI programami, ako Alpine, Mutt či htop (s príkazom top však áno, pretože sa spúšťa jeho imitácia napísaná v eLispe). Ale existuje možnosť pre tento prípad pustiť inštanciu term (resp. ansi-term), ktorá tieto veci zvládne.
Nastavením príslušného zoznamu:

(setq eshell-visual-commands
   (quote
    ("alpine -i" "screen" "top" "less" "more" "ncdu" "alpine" "htop" "most")))


Obr. 3: TUI mailový klient "Alpine" spustený v ansi-term-e

Ani tu nie sme chudobnení o pohyb kurzora všetkými smermi - anti-term či term dokážu pracovať v dvoch režimoch (term-char-mode a term-line-mode), medzi ktorými sa dá samozrejme prepínať i skratkou (C-c C-k resp. C-c C-j).

 

Ďalšie rozšírenia

Autojump

…je rozšírenie na uľahčenie prepínania medzi adresármi. Zadaním j bez argumentov sa zobrazí zoznam obľúbených adresárov; pomocou j <regexp> je možné sa do adresáru presunúť. Zoznam adresárov je tvorený frekvenciou ich používania. K tomu to je potrebný balík eshell-autojump.

 

Helm-eshell-history

Okrem toho existuje i história cd príkazov, po zadaní cd = je možná voľba (pomocou čísla) zo zoznamu. Nie je to zlé, ale ak už máme inštalovaný rozširujúci framework helm, môžeme použiť príkaz helm-eshell-history, ktorý nám umožňuje v histórii (fuzzy) vyhľadávanie a samozrejme vkladanie minulých príkazov na pozíciu kurzora v eshelli.


Obr. 4: Vylepšená práca s históriou príkazov

Súvisiacou vlastnosťou je i helm-eshell-prompts, ktorý nám umožňuje presun kurzoru na minulý príkaz - defacto listuje v bufferi po minulých príkazoch podobne ako eshell-next(previous)-prompt, ale vizuálne.

 

Autodopĺňanie

Vraveli sme, že Emacs je majster práce s textom? No asi niekoľkokrát a stále je to pravda. A automatické dopĺňanie k práci s textom neodmysliteľne patrí.

Dopĺňanie je možné viacerými spôsobmi, ktoré sa dajú navzájom kombinovať.

 

1. Dopĺňanie názvov súborov a príkazov
Proste klasika ako v bash-i, po stlačení TAB. Toto je základná funkcionalita out-of-box, ktorá nikoho neohúri, hádam iba človeka, ktorý do včera používal DOS.

 

2. Dopĺňanie navyše i parametrov príkazov
Teda identické správanie ako v zsh alebo fish shelli.
Je potrebné mať k tomu nainštalované fish doplnenia (najjednoduchšie nainštalovaním samotného fish), ktoré sa zvyčane nachádzajú v ~/.local/share/fish a ~/.local/etc/fish.
Ďalej je potrebný balík Emacsu s názvom helm-fish-completion.
A počas zadávania je sa po spustení rovnomenného príkazu (alebo nastavenej klávesovej skratke (napr. i znovu TAB)) sa objaví táto nádhera:

Obr. 5: Doplnenie nekonečných parametrov príkazu Tar


Obr. 6: Doplnenie parametrov príkazu Apt

 

3. Dopĺňanie pomocou Abbrev
Abbrev je základnou funkcionalitou Emacsu, ktorá je vždy predinštalovaná. Umožňuje pomocou zadania niekoľných znakov (stačí i jeden) a volaním príkazu dabbrev-expand listovať medzi výskytmi reťazca (predvolene) v aktuálnom bufferi.

Napríklad na snímke obrazovky nižšie som zadal rt a následne som stlačil niekoľko-krát M-/, až do zvolenia požadovaného doplnenia.


Obr. 7: Doplnenie názvu súboru pomocou Abbrev

 

4. Dopĺňanie pomocou Auto-complete
… je podobné predchádzajúcemu dopĺňaniu, ale s využitím vyskakovacieho menu. Toto sa objaví automaticky po zadaní 3 znakov (ak nie je inak určené inak) a predvolene dopĺňa z aktuálneho bufferu, ale dokáže i z iných bufferov či zo slovníka. Primárne je to rozšírenie určené pre programovanie, ale v Emacse je možné všetko spolu dokombinovať (a aj domotať ☺). Len dodám, že toto rozšírenie je potrebné doinštalovať.


Obr. 8: Doplnenie názvu súboru pomocou vyskakovacieho menu

 

App-launcher

Veľa ľudí, mňa nevynímajúc, preferuje spúšťanie aplikácií (to starom "programov") zadaním (časti) ich názvu pred klikaním v štruktúre menu alebo na ikony. Launcher-ov existuje mnoho, napr. dmenu, App Select či gExec. A táto šikovná vec je implementovaná i v rozšírení s názom app-launcher. Po jeho spustení sa objaví zoznam inštalovaných programov (jedná sa o vylistovanie .desktop súborov (globálnych, i lokálnych v ~.local/share/applications/). Zadaním časti názvu sa dynamicky zoznam zužuje.


Obr. 9: Launcher na spúštanie programov

Upload na 0x0 a iné…

Často používam službu https://0x0.st/ na dočasné uloženie veľkého súboru, ktorý by emailom neprešiel. Doteraz som používal skript, v ktorom sa nahrávanie robilo pomocou curl -F'file=<súbor> https://0x0.st.
Avšak existuje i rozšírenie 0x0.el, ktoré túto činnosť zjednodušuje a výsledný odkaz priamo "hodí" do kill-ring-u.
Existujú podobné rozšírenia na dočasné emaily, skracovače URL adries, upload a download na YouTube či Invidious.

 

A teraz negatíva

K zodpovednej recenzii patrí aj kritika. Aj keď sa jedná o Emacs, ktorý vzbudzuje extrémne emócie oboma smermi.
Hlavné nedostatky eshell-u:

 

Eshell ako vyskakovací terminál

V minulosti som veľmi často používal emulátor terminálu s názvom Tilda. Podobné sú napr. Guake či Yakuake, čo všetko sú terminály, ktoré sa po stlačení klávesovej skratky vyrolujú z vrchu, podobne ako terminál v hre Quake (čo nemôžem potvrdiť, lebo to tú hru nikdy nehral, ale napríklad Hexen II áno, a tam to tiež takto bolo).
Ale ako to spraviť s eshell-om, aby bol stále poruke?

Riešenie je možné pomocou programu tdrop (https://github.com/noctuid/tdrop). Je to výborný program, ktorý pridá túto vyskakovaciu parádičku ku hocijakému programu, pričom používa programy ako xprop (na zistenie vlastností okna), xdotool (na zmenu veľkosti a polohy okna) a xwininfo (na o.i. zmenu názvu okien).

Skompilovanú binárku z GitHub-u som stiahol a v súbore okenného manažéra, v ktorom sa definujú klávesové skratky (v mojom prípade je okenným manažérom IceWM a teda sa jedná o súbor ~.icewm/keys - ale určite existuje analogické riešenie pre každý okenný manažér, o desktopových prostrediach nehovoriac) som zadefinoval:

key "Ctrl+Menu"	       ~/bin/tdrop/tdrop -ma -h 95% -w 98% -y 30 -s  dropdown emacs -f eshell  -title Eshell

Čo spôsobí:

parameterakcia
-maautomatické zistenie manažéra a rozlíšenie
-h 95%nastavenie výšky vyskočeného okna (dá sa i absolútne)
-w 98%detto šírka
-y 30

offset (posun) okna voči ľavému hornému roku

(nechcel som, aby mi vyskočené okno prekrylo nástrojovú lištu)

dropdownpotrebný vnútorný príkaz
emacs -f eshellkonkrétny program s parametrami (v našom prípade emacs so zavolaním funkcie "eshell")
-title Eshellnázov novo vytvoreného vyskakovacieho okna

 

Záver

Verím, že som opísal všetky podstatné vlastnosti eshell-u a verím, že v dobrom svetle. Kto používa Emacs, a doteraz eshell neskúsil, nech neváha a pravdepodobne po úvodných nadávkach si na neho privykne a už s ním zostane.
Môže byť vhodným nástrojom i pre tých, ktorí musia občas do smutného sveta MS Windows a súčasne chcú mať zachovanú spomienku na GNU/Linux.

    • RE: BASH, ZSH, FISH. A čo takto Eshell? 11.01 | 14:32
      Avatar vxmery Mint 19.3 Cinnamon  Používateľ

      Pekne spracované aj zrozumiteľne podané, dobrá práca Rišo

      • RE: BASH, ZSH, FISH. A čo takto Eshell? 12.01 | 08:40
        Avatar Richard Antix  Používateľ

        Ďakujem.

        Na editoroch Emacs či Vi(m) je zaujímavé, že trvá dlhú dobu, kým dôjde k ich uspokojivému ovládaniu. Ale nie je to strata času - ten sa totiž vráti pri ich používaní.
        Takže sťažnosť: "Nemám čas učiť sa ich!" sa dá obrátiť na "Nemôžem strácať čas ich nepoužívaním!".