A fish két, egymásra épülő eszközt kínál a gyakran ismételt parancsok lerövidítésére: az aliast és a functiont. Elsőre könnyű azt hinni, hogy ez a bash-ből ismert alias egy az egyben átültetve, de a fish ennél jóval mélyebbre megy — sőt, ahogy látni fogjuk, az alias valójában maga is egy function, csak egy nagyon egyszerűsített formában. Ez a cikk sorra veszi mindkettőt: hogyan működnek a motorháztető alatt, mire jók, mikor érnek véget a lehetőségeik, és hol kezdődik az, amit már csak valódi functionnel érdemes megoldani.
1. Az alias — gyors parancshelyettesítés
1.1 Mi történik valójában
A fish alias parancsa nem külön nyelvi elem, hanem egy beépített wrapper a function köré. Amikor ezt írod:
alias rmi="rm -i"
a fish a háttérben pontosan ezt hozza létre:
function rmi --wraps rm --description 'alias rmi=rm -i'
rm -i $argv
endEz két fontos dolgot árul el. Egyrészt: az alias automatikusan hozzáfűzi a $argv-t a parancs végéhez, tehát minden paramétert, amit az alias után írsz, továbbad az eredeti parancsnak. Másrészt: mivel valódi function jön létre, ugyanazokkal az eszközökkel (functions, funced, funcsave) kezelhető, mint bármelyik kézzel írt function.
1.2 Létrehozás és szintaxis
Kétféle írásmód is működik:
alias ll 'ls -la' alias ll='ls -la'
Szóközt tartalmazó parancsoknál figyelni kell az idézőjelezésre — pontosan úgy, mintha a parancssorba írnád be:
alias chrome='/opt/google/chrome/chrome\ browser'
1.3 Ideiglenes vagy végleges
Alapból az alias csak az aktuális shell-munkamenetre érvényes, új terminál nyitásakor eltűnik. Három út vezet a véglegesítéshez:
a) --save (vagy -s) kapcsoló — ez a legrövidebb út, egy lépésben menti a ~/.config/fish/functions/ könyvtárba:
alias --save ll 'ls -la'
b) funcsave külön lépésben:
alias ll 'ls -la' funcsave ll
Ez ugyanoda ment egy ll.fish fájlt, ami a fish autoload-mechanizmusa miatt minden induláskor automatikusan elérhető lesz — nem kell semmit sourceolni.
c) Bekerül a config.fish-be:
# ~/.config/fish/config.fish alias ll 'ls -la' alias gs 'git status' alias update 'sudo apt update; and sudo apt upgrade'
Ez minden induláskor újra lefuttatja az alias parancsokat. Előnye, hogy az összes rövidítésed egy helyen, jól áttekinthetően, verziókezelhető dotfiles-ként tartható. Hátránya, hogy sok tucat alias esetén ez apró késést ad a shell indulásához, míg a funcsave-es, autoload-olt fájlok csak akkor töltődnek be, amikor ténylegesen meghívod őket.
1.4 Az alias korlátai
Itt érdemes megállni egy fontos csapdánál. Mivel az alias mindig hozzáfűzi a $argv-t a teljes definíció végéhez, összetett, több parancsból álló alias esetén az eredmény meglepő lehet:
alias mentes "cp -r ~/dokumentumok /backup; du -sh /backup"
Ha ezt paraméterrel hívod (mentes valami), a valami csak a második parancshoz, a du -sh /backup-hoz fog odaragadni, nem oda, ahová logikusan várnád. Az alias tehát jól működik egyetlen parancs egyszerű kiegészítésére vagy rövidítésére, de amint elágazás, ciklus, több lépés vagy paraméterek okos elhelyezése kell, a function az útja.
1.5 Aliasok kezelése
alias # listázza az összes, alias-ból származó functiont functions -e ll # törli (az alias-t is így kell törölni, nincs külön "unalias")
2. A function — amikor az aliasnál többre van szükség
2.1 Alapszintaxis
function nev
parancsok
endA $argv itt is elérhető, de listaként, index szerint is olvasható ($argv[1], $argv[2], $argv[1..2]), és a count $argv megadja a paraméterek számát. A fish 1-től indexel, nem 0-tól. Mert sok helyen 0-tól indul, így biztosan lesz aki ebbe jól belekeveredik. A Linux és egyéb dolgok nagy hátránya, hogy nincsenek szabványosított dolgok, csak szokásjogi elvárások. Amit vagy betartanak, vagy nem.
function udvozles
echo "Szia, $argv[1]!"
end2.2 Feltételek, ciklusok, elágazás
A function belsejében a teljes fish nyelv rendelkezésre áll — if/else, for, while, switch/case, and/or láncolás (a fish ezeket használja &&/|| helyett), saját exit kóddal (return), és set -l-lel lokális, csak a functionre érvényes változókkal.
function ujdir --description 'Könyvtár létrehozása és belépés'
if test (count $argv) -eq 0
echo "Használat: ujdir "
return 1
end
mkdir -p $argv[1]; and cd $argv[1]
end2.3 --description, --wraps és a completion-öröklés
A --description a functions és a tab-completion súgójában jelenik meg. A --wraps ennél praktikusabb: azt mondja a fishnek, hogy ez a function egy másik parancsot csomagol be, ezért örökölje annak tab-completionjeit.
function ll --wraps ls --description 'ls, olvashatóbb kimenettel'
ls -lh --color=auto $argv
endEmiatt a ll után nyomott Tab pontosan úgy kínálja fel a fájlneveket és az ls kapcsolóit, mintha ls-t írnál — ezt egy sima alias is megkapja automatikusan, de saját, több lépéses functionnél ezt külön be kell írnod, ha szeretnéd ezt a kényelmet.
2.4 Komplex kapcsolók: argparse
Amint egy function több kapcsolót is kezel (-c, --jobs 4 stb.), a kézi $argv-turkálás helyett az argparse a helyes eszköz:
function build --description 'Projekt fordítása make-kel'
argparse 'c/clean' 'j/jobs=' -- $argv
or return
if set -q _flag_clean
make clean
end
if set -q _flag_jobs
make -j $_flag_jobs
else
make
end
endItt a c/clean egy kapcsoló nélküli (bool) flaget definiál, a j/jobs= pedig egy értéket vár. Az argparse minden felismert kapcsolóhoz létrehoz egy _flag_x / _flag_hosszunev változót, a fel nem ismert argumentumok pedig a megtisztított $argv-ban maradnak.
2.5 Automatikus futás eseményekre: --on-variable, --on-event
A function nem csak kézzel hívható — kötheted változó módosulásához vagy fish-eseményhez is. Klasszikus példa: automatikus ls minden könyvtárváltáskor:
function _auto_ls --on-variable PWD --description 'Automata ls könyvtárváltáskor'
ls
endEz a functions mappába mentve minden cd után lefut, mert a PWD universal-szerűen figyelt változó módosulására reagál.
2.6 Fenntartott nevek és óvatosság
A functionök nem viselhetik a fish nyelvi kulcsszavainak nevét (if, for, function, switch, argparse stb.), és kerülendő, hogy egy meglévő beépített paranccsal azonos nevű, de eltérő viselkedésű functiont hozz létre — ez könnyen okoz zavart saját magadnak vagy más scriptjeidnek, amik a beépített viselkedésre számítanak. Ha csak interaktív kényelemről van szó (pl. ls mindig színesen fusson), arra inkább az abbr illik jobban (lásd lentebb).
3. Mentés, szerkesztés, autoload
| Parancs | Mit csinál |
|---|---|
| functions | Kilistázza az összes definiált functiont |
| functions nev | Kiírja egy adott function forráskódját |
| functions -e nev | Törli a functiont (aliasnál is ezt kell) |
| funced nev | Megnyitja a functiont $EDITOR-ban szerkesztésre |
| funcsave nev | Elmenti a jelenleg memóriában lévő definíciót fájlba |
A fish autoload a lényeg, ami miatt ritkán kell bármit is kézzel sourceolni: ha egy nev.fish fájl bekerül a ~/.config/fish/functions/ könyvtárba (pontosan a function nevével egyező fájlnévvel), a fish az első hívásnál automatikusan betölti — nem kell újraindítani a shellt, nem kell semmit source-olni. Ezért a legegyszerűbb módja egy új function létrehozásának, ha közvetlenül ide írsz egy fájlt:
# ~/.config/fish/functions/extract.fish
function extract --description 'Archívum kicsomagolása kiterjesztés alapján'
if not test -f $argv[1]
echo "A fájl nem létezik: $argv[1]"
return 1
end
switch $argv[1]
case '*.tar.bz2'
tar xjf $argv[1]
case '*.tar.gz' '*.tgz'
tar xzf $argv[1]
case '*.zip'
unzip $argv[1]
case '*.rar'
unrar x $argv[1]
case '*.7z'
7z x $argv[1]
case '*'
echo "Nem támogatott formátum: $argv[1]"
return 1
end
endEzt elmentve azonnal használható, semmilyen config.fish-módosítás nem kell hozzá.
4. Életszerű példák
4.1 Alias-szintű rövidítések
alias --save ll 'ls -lh --color=auto' alias --save la 'ls -lha --color=auto' alias --save gs 'git status' alias --save gp 'git pull' alias --save vim 'nvim' alias --save df 'df -h'
4.2 mkcd — könyvtár létrehozása és belépés egy lépésben
function mkcd --description 'mkdir -p, majd cd egy lépésben'
if test (count $argv) -eq 0
echo "Használat: mkcd "
return 1
end
mkdir -p -- $argv[1]; and cd -- $argv[1]
end4.3 backup — időbélyeges biztonsági másolat
function backup --description 'Fájl(ok) másolása .bak kiterjesztéssel, dátummal'
if test (count $argv) -eq 0
echo "Használat: backup fájl1 [fájl2 ...]"
return 1
end
for file in $argv
cp -a -- $file $file.(date +%Y%m%d_%H%M%S).bak
end
end4.4 gcm — git commit ellenőrzéssel
function gcm --description 'git commit -m üzenet-ellenőrzéssel'
if test (count $argv) -eq 0
echo "Használat: gcm 'commit üzenet'"
return 1
end
git commit -m "$argv"
end4.5 longrun — értesítés egy hosszabb parancs végén
Kifejezetten hasznos forduló build-eknél vagy nagyobb másolásoknál:
function longrun --description 'Parancs futtatása, majd asztali értesítés'
eval $argv
set -l exit_code $status
if test $exit_code -eq 0
notify-send "Kész ✔" "Lefutott: $argv"
else
notify-send "Hiba ✘" "Sikertelen ($exit_code): $argv"
end
endHasználat: longrun make -j8.
5. Bónusz: az abbr, a modern alternatíva
A fish dokumentációja maga is azt javasolja, hogy interaktív, gyakran gépelt rövidítésekhez inkább az abbr-t érdemes használni alias helyett. A különbség lényegi: az abbr élőben, gépelés közben helyettesíti be a rövidítést a teljes paranccsal, mielőtt az lefutna — tehát a shell-előzményekben (és képernyőmegosztás, oktatóvideó esetén a nézőknek) mindig a teljes, valódi parancs látszik, nem a rövidítés.
abbr --add gco git checkout abbr --add L --position anywhere "| less"
Itt a gco begépelése és szóköz/Enter lenyomása után a parancssorban ténylegesen git checkout jelenik meg, mielőtt lefutna. Fontos gyakorlati részlet: a fish 3.6 óta az abbr-eket nem menti automatikusan univerzális változóba — ezeket a config.fish-ba (vagy egy külön conf.d/ fájlba) kell felvenni, ugyanúgy, ahogy az aliasokat szokás.
Egy tömör ökölszabály a háromhoz:
| Eszköz | Mikor jó | Korlát |
|---|---|---|
| abbr | Interaktív gyorsírás, ahol jó látni a teljes parancsot | Csak interaktív módban működik, scriptben nem |
| alias | Egyetlen parancs egyszerű, fix kiegészítése | Több parancs / összetett logika esetén megbízhatatlan a $argv elhelyezése |
| function | Több lépés, feltétel, ciklus, saját kapcsolók, esemény-vezérelt futás | Kicsit több gépelés, de cserébe teljes nyelv áll rendelkezésre |
Összefoglalás
A fish-ben az alias valójában csak egy kényelmi „gyorsbillentyű” a function-építéshez — pont ezért nem véletlen, hogy ugyanazokkal a parancsokkal (functions, funcsave, funced) kezelhető, mint egy kézzel írt function. Amíg egyetlen parancs rövid formájáról van szó, az alias (vagy még inkább az interaktív használatra szánt abbr) tökéletesen elég. Amint feltétel, ciklus, több lépés, saját kapcsoló vagy automatikus esemény-vezérelt futás merül fel, érdemes egyenesen a functionhöz nyúlni, és a ~/.config/fish/functions/ könyvtárban, önálló fájlként tárolni — ez a fish natív, autoload-ra épülő megközelítése, ami gyors indulást és jól karbantartható, egy fájl/egy function szerkezetet ad.
Tipp:
Ha nem vagy jártas a programozásban, vagy nagyon összetett megoldásokat szeretnél, akkor használj mesterséges intelligenciát! Gyors és kényelmes megoldás, ha normálisan le tudod írni a kívánságaidat. Illetve az interneten sok előre kész megoldást találsz, hiszen a fish shell egy nagyon elterjedt, kényelmes shell, amit sok linux disztribúció alapból kínál.

Hozzászólások
Egy időben el sem tudtam
Beküldte berus -
Értékelés:
Egy időben el sem tudtam képzelni az életet fish nélkül, aztán amikor egyre több saját szkriptet kezdtem használni, akkor a hordozhatóság/kompatibilitás miatt ezek mindig bash-ben íródtak. Egy ideig játszottam, hogy mindennapi használat fish, szkript írás bash, aminek az lett a vége, hogy fish lassan kikopott az életemből...
De most meghoztad a kedvem, hogy ránézzek (a 4-es sorozatot még nem is láttam), és volt pár újdonság is, amit nem tudtam, köszi!