fish
23. November 2019 (letzte Änderung am 29. Mai 2022)
Die fish (friendly interactive shell) hat mich wegen dieser Funktionen überzeugt:
- Syntax-Highlighting in der Kommandozeile
- Vorschläge während der Eingabe eines Kommandos
- Intuitives Durchsuchen der History mit der ↑-Taste
- Tab-Vervollständigung auf Basis von man-Pages
Die Installation ist einfach und ich musste nicht viel konfigurieren bis ich mir sicher war, dass ich die bash als Standard-Shell ersetzen wollte.
Installation
Arch Linux
sudo pacman -S fish
Ubuntu 20.04
Da in den Standardpaketen vieler Linux-Distributionen oft nicht die aktuellsten Versionen enthalten sind, empfehle ich, in Ubuntu 20.04 das fish-shell-PPA hinzuzufügen:
sudo apt-add-repository ppa:fish-shell/release-3
sudo apt-get update
sudo apt-get install fish
Alternativ kann man auch die .deb
-Pakete runterladen und dann installieren mit
dpkg -i fish_3.4.1-1~focal_amd64.deb
Konfiguration
Die Konfiguration kann teilweise über den Browser durchgeführt werden. Das Kommando fish_config
öffnet die Konfigurationsseite. Da kann zum Beispiel ein Farbschema und ein vorkonfigurierter Prompt ausgewählt werden (ich benutze Informative Vcs).
Weitergehende Eintstellungen erfolgen in der Datei ~/.config/fish/config.fish
(entspricht der ~/.bashrc
). Hier ein Beispiel:
# load aliases
if [ -f $HOME/.config/fish/aliases.fish ]
source $HOME/.config/fish/aliases.fish
end
# don't shorten path in prompt
set -U fish_prompt_pwd_dir_length 0
Aliasse / Abbreviations
bash-Aliasse funktionieren in der Regel auch in der fish. Dafür kann man einfach die .bash_aliases
kopieren
cp ~/.bash_aliases ~/.config/fish/aliases.fish
und wie im Beispiel oben einbinden.
Eventuell sind kleine Anpassungen nötig, wenn im Alias Variablen gesetzt werden oder wenn ANSI-C Strings verwendet werden (alias xy=$'\'complicated\' \"command\"'
). Außerdem können in fish Aliasse keine anderen Aliasse aufrufen.
Zusätzlich zu Aliassen gibt es in fish noch Abbreviations. Diese sind Aliassen sehr ähnlich. Sie unterscheiden sich dadurch, dass sie während der Eingabe nach einem Leerzeichen oder Return expandiert werden und dass sie verkettet werden können. Beispiel:
abbr rsyncp 'rsync --info=progress2 -ah'
Wichtige Unterschiede zwischen bash und fish als interaktive Shell
bash | fish | Erläuterung |
---|---|---|
y=5 | set y 5 | Variablenzuweisung mit set |
export y=5 | set -x y 5 | Variablen exportieren mit set -x oder set --export |
mkdir "$folder" | mkdir $folder | Variablen mit Leerzeichen müssen nicht in Anführungszeichen stehen |
$(command) oder `command` | (command) oder $(command) | Kommando-Substitution in einfachen Klammern. fish unterstützt seit Version 3.4.0 auch die POSIX-Schreibweise $(command) |
$? | $status | Exit status des letzten Kommandos |
Wenn du ein bash-Kommando in der fish-Shell ausführen möchtest, sind manchmal kleine Anpassungen notwendig (wie in der obenstehenden Tabelle aufgelistet).
Beispiele:
-
Kann unverändert in die fish eingefügt werden:
cd ~/workspace && git clone --depth 1 https://github.com/junegunn/fzf.git
-
In fish-Versionen < 3.4.0 muss hier das
$
-Zeichen entfernt werden:ps wup $(pgrep -f python)
-
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
muss ersetzt werden durch
set -x JAVA_HOME /usr/lib/jvm/java-11-openjdk-amd64
-
Um einen größeren Code-Block auszuführen, kann auch einfach kurz in die bash gewechselt werden:
~ ▶ bash ~ $ awk 'BEGIN{ > s="/\\/\\/\\/\\/\\"; s=s s s s s s s s; > for (colnum = 0; colnum<77; colnum++) { > r = 255-(colnum*255/76); > g = (colnum*510/76); > b = (colnum*255/76); > if (g>255) g = 510-g; > printf "\033[48;2;%d;%d;%dm", r,g,b; > printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b; > printf "%s\033[0m", substr(s,colnum+1,1); > } > printf "\n"; > }' [Ausgabe] Zurück zur fish mit Strg-D ~ ▶
Funktionen/Shortcuts
Funktion | bash | fish |
---|---|---|
vorheriges Wort löschen | Ctrl+w | |
nächstes Wort löschen | Alt+d | |
letztes Argument des letzten Kommandos einfügen | Alt+. | |
Undo | Ctrl+_ | Ctrl+_ / Ctrl+z |
Alias expandieren | Ctrl+Alt+e | ✘ |
Bis Wortende in Großbuchstaben umwandeln | Alt+u | |
Bis Wortende in Kleinbuchstaben umwandeln | Alt+l | ✘ |
Nächstes Zeichen explizit einfügen | Ctrl+v | ✘ |
Zeile auskommentieren und neue beginnen | Alt+# | |
Leerzeichen um den Cursor löschen | Alt+\ | ✘ |
Aktuelle Zeile in $EDITOR bearbeiten |
Ctrl+x Ctrl+e | Alt+e |
Während Eingabe Inhalt des aktuellen Ordners anzeigen | ✘ |
Alt+l |
sudo vorne einfügen |
✘ |
Alt+s |
&| less; hinten anhängen (p wie Pager) |
✘ |
Alt+p |
bash vs fish als Skriptsprache
Wer fish als interaktive Shell benutzt, muss nicht zwangsläufig auch fish-Skripte schreiben. Ich schreibe ganz triviale Skripte nach Möglichkeit POSIX-konform, damit sie mit der extrem schnellen Dash ausgeführt werden können. Für große Projekte benutze ich Python. Für alles dazwischen benutze ich lieber fish als bash, weil in fish vieles logischer oder benutzerfreundlicher ist als in bash.
Hier ein paar Beispiele, wie man Dinge in bash und in fish schreibt:
bash | fish | Erläuterung |
---|---|---|
echo ${var,,} | string lower $var | Variable in Kleinbuchstaben umwandeln |
var="${var#"${var%%[![:space:]]*}"}" | string trim $var | Variable ohne Leerzeichen am Anfang und am Ende ausgeben |
if [[ ":$PATH:" == *":/bin:"* ]]; then | if contains /bin $PATH | Testen, ob /bin in $PATH enthalten ist |
echo ${#arr[@]} | count $arr | Die Länge eines Arrays ausgeben |
echo $(tput setaf 4)blue$(tput sgr0)xx | echo (set_color blue)blue(set_color normal)xx | Ein farbiges Wort ausgeben |
Alternativen / Warum nicht zsh?
Wie vermutlich die meisten Linux-Nutzer habe ich jahrelang die bash benutzt, einfach nur weil sie in den meisten Distributionen die Standard-Shell ist.
Vor einem Jahr hab ich mal die zsh (+ohmyzsh) ausprobiert, weil mir die Tab-Funktionalität und die Git-Information im Prompt dort gefallen haben. Aber dafür haben mich ein paar andere Dinge gestört: Zum Beispiel kann man in der bash mit Alt+Backspace das letzte Wort und mit Ctrl+w alles bis zum letzten Leerzeichen (also etwa einen kompletten Dateipfad) löschen. In der zsh machen beiden Tastenkombinationen das Gleiche. Wie unsinnig! Und eine Tab-Vervollständigung mit Tab und Auswahl mit den Pfeiltasten sieht auch nur auf den ersten Blick praktisch aus (weil das Rübergreifen zu den Pfeiltasten auch nicht schneller geht, als die Suche durch ein paar zusätzliche Buchstaben weiter einzugrenzen). Ich hab dann letztendlich lieber das Tab-Verhalten und den Prompt in der bash angepasst und war damit zufrieden. Wer sowieso schon die zsh benutzt, kann sich aber auch die besten Funktionen der fish (automatische Vorschläge und Syntax-Highlighting) per Plugin nachladen.
Weil ich sehr gerne in Python programmiere, finde ich auch die xonsh (Pythonish, BASHwards looking shell) sehr interessant. Ich weiß nur noch nicht, ob ich die leicht erhöhten Ladezeiten für ein neues Fenster/einen neuen Tab in Kauf nehmen möchte, wo ich die Vorteile der xonsh vermutlich kaum nutzen würde.