fish

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

Die Installation ist unter Ubuntu gewohnt einfach:

sudo apt-get install fish

Damit bekommt man unter Ubuntu 18.04 aber nur fish 2.7.1. Ich empfehle jedoch die aktuelle Version (zur Zeit 3.1.0, Standard in Ubuntu 20.04), weil diese auch die Verkettung von Kommandos mit && unterstützt. In fish 2.7 geht das nur mit ; and.

Die neue Version gibt's über ein PPA:

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.1.0-1~bionic_amd64.deb fish-common_3.1.0-1~bionic_all.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'

Hauptunterschiede zur bash

bashfishErläuterung
y=5set y 5Variablenzuweisung mit set
export y=5set -x y 5Variablen exportieren mit set -x oder set --export
mkdir "$folder"mkdir $folderVariablen mit Leerzeichen müssen nicht in Anführungszeichen stehen
$(command) oder `command`(command)Kommando-Substitution in einfachen Klammern
$?$statusExit 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:

  1. Kann unverändert in die fish kopiert werden:
    cd ~/workspace && git clone --depth 1 https://github.com/junegunn/fzf.git
  2. Hier muss das $-Zeichen entfernt werden:
    ps wup $(pgrep -f python)
  3. 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
  4. 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

Funktionbashfish
vorheriges Wort löschen Ctrl+w
nächstes Wort löschen Alt+d
letztes Argument des letzten Kommandos einfügen Alt+.
Undo Ctrl+_
Ctrl+x Ctrl+e
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

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.