Fisch - Freundliche interaktive Shell¶
Fish (Freundlich Interactive Shell) ist eine intelligente und benutzerfreundliche Kommandozeilenhülle, die für interaktive Nutzung, Usability und Entdeckbarkeit konzipiert ist. Erstellt von Axel Liljencrantz im Jahr 2005, Fish nimmt eine andere Herangehensweise von traditionellen Shells, indem es Benutzererfahrung priorisiert und vernünftige Standardeinstellungen aus der Box. Im Gegensatz zu POSIX-konformen Schalen, Fisch verfügt über Syntax-Highlighting, Autovorschläge, Tab-Vervollständigungen, die ohne Konfiguration arbeiten, und eine saubere, moderne Syntax, die darauf abzielt, intuitiver und weniger fehleranfälliger als herkömmliche Shell-Sprachen zu sein.
Installation und Inbetriebnahme¶
Installation von Fish Shell¶
```fish
Ubuntu/Debian¶
sudo apt update && sudo apt install fish
CentOS/RHEL/Fedora¶
sudo dnf install fish
macOS (using Homebrew)¶
brew install fish
Arch Linux¶
sudo pacman -S fish
FreeBSD¶
pkg install fish
From source (latest version)¶
git clone https://github.com/fish-shell/fish-shell.git cd fish-shell cmake . make sudo make install ```_
Fish als Standard Shell¶
```fish
Check Fish installation¶
which fish /usr/bin/fish
Add Fish to available shells¶
echo /usr/bin/fish|sudo tee -a /etc/shells
Set Fish as default shell¶
chsh -s /usr/bin/fish
Verify change (restart terminal)¶
echo $SHELL ```_
Erst-Zeit-Setup¶
```fish
Start Fish shell¶
fish
Fish will create configuration directory automatically¶
~/.config/fish/¶
Run Fish configuration wizard¶
fish_config
This opens a web-based configuration interface¶
Accessible at http://localhost:8000¶
```_
Grundkonfiguration Struktur¶
```fish
Fish configuration files¶
~/.config/fish/config.fish # Main configuration file ~/.config/fish/functions/ # Custom functions directory ~/.config/fish/completions/ # Custom completions directory ~/.config/fish/conf.d/ # Additional configuration files
Create basic config.fish¶
mkdir -p ~/.config/fish cat > ~/.config/fish/config.fish << 'EOF'
Fish configuration¶
Set environment variables¶
set -gx EDITOR vim set -gx BROWSER firefox
Add to PATH¶
set -gx PATH $HOME/bin $PATH set -gx PATH $HOME/.local/bin $PATH
Aliases¶
alias ll 'ls -alF' alias la 'ls -A' alias l 'ls -CF'
Custom greeting¶
set fish_greeting "Welcome to Fish Shell!" EOF ```_
Fischsyntax und Spracheigenschaften¶
Variablen und Geltungsbereich¶
```fish
Variable assignment (no $ for assignment)¶
set name "John Doe" set age 30 set path "/home/user"
Using variables ($ required for expansion)¶
echo $name echo "Hello, $name" echo "Age: $age"
Variable scopes¶
set -l local_var "local" # Local to current scope set -g global_var "global" # Global to current session set -U universal_var "universal" # Universal across all sessions set -x exported_var "exported" # Exported to child processes
Multiple assignment¶
set fruits apple banana orange echo $fruits[1] # apple (1-indexed) echo $fruits[2] # banana echo $fruits[-1] # orange (last element)
Array operations¶
set fruits $fruits grape # Append set fruits[2] kiwi # Replace element set -e fruits[1] # Erase element ```_
Kommando Substitution¶
```fish
Command substitution using parentheses¶
set current_date (date) set file_count (ls|wc -l) set user_home (eval echo ~$USER)
Nested command substitution¶
echo "Today is "(date +%A)", "(date +%B)" "(date +%d)
Store command output in variable¶
set git_branch (git branch --show-current 2>/dev/null) if test -n "$git_branch" echo "Current branch: $git_branch" end ```_
String Manipulation¶
```fish
String operations¶
set string "Hello, World!" echo (string length "\(string") # String length echo (string sub -s 1 -l 5 "\)string") # Substring (Hello) echo (string replace "Hello" "Hi" "\(string") # Replace echo (string upper "\)string") # Uppercase echo (string lower "$string") # Lowercase
String splitting and joining¶
set words (string split " " "$string") echo $words[1] # Hello, set rejoined (string join "-" $words) echo $rejoined # Hello,-World!
Pattern matching¶
if string match -q "Hello*" "$string" echo "String starts with Hello" end
Regular expressions¶
if string match -qr "W\w+d" "$string" echo "String contains word starting with W and ending with d" end ```_
Bedingte Aussagen¶
```fish
if-then-else¶
if test $age -gt 18 echo "Adult" else if test $age -eq 18 echo "Just turned adult" else echo "Minor" end
Test conditions¶
if test -f "file.txt" # File exists echo "File exists" end
if test -d "directory" # Directory exists echo "Directory exists" end
if test "$var" = "value" # String equality echo "Variable equals value" end
if test $num -eq 10 # Numeric equality echo "Number is 10" end
Logical operators¶
if test $age -gt 18; and test $age -lt 65 echo "Working age" end
if test $status -eq 0; or test $force = "true" echo "Success or forced" end
if not test -f "file.txt" echo "File does not exist" end
Switch statement¶
switch $file_extension case "txt" echo "Text file" case "jpg" "png" "gif" echo "Image file" case "*" echo "Unknown file type" end ```_
Loops und Iteration¶
```fish
for loop¶
for i in (seq 1 10) echo "Number: $i" end
for file in *.txt echo "Processing: $file" end
for item in $array echo "Item: $item" end
while loop¶
set counter 1 while test $counter -le 10 echo "Counter: $counter" set counter (math $counter + 1) end
Loop control¶
for i in (seq 1 10) if test $i -eq 5 continue # Skip iteration end if test $i -eq 8 break # Exit loop end echo $i end ```_
Funktionen und Skripten¶
Beschreibung der Funktion¶
```fish
Basic function¶
function greet echo "Hello, $argv[1]!" end
Function with description¶
function greet --description "Greet a user" echo "Hello, $argv[1]!" end
Function with argument validation¶
function calculate_sum --description "Calculate sum of two numbers"
if test (count $argv) -ne 2
echo "Usage: calculate_sum
math $argv[1] + $argv[2]
end
Function with local variables¶
function process_file --description "Process a file" set -l filename \(argv[1] set -l line_count (wc -l < "\)filename") echo "File $filename has $line_count lines" end ```_
Erweiterte Funktionen¶
```fish
Function with options¶
function my_ls --description "Enhanced ls with options" argparse 'l/long' 'a/all' 'h/help' -- $argv or return
if set -q _flag_help
echo "Usage: my_ls [-l|--long] [-a|--all] [directory]"
return
end
set -l ls_args
if set -q _flag_long
set ls_args $ls_args -l
end
if set -q _flag_all
set ls_args $ls_args -a
end
ls $ls_args $argv
end
Function with completion¶
function mycommand --description "Custom command with completion" switch $argv[1] case "start" echo "Starting service" case "stop" echo "Stopping service" case "status" echo "Service status" case "*" echo "Usage: mycommand \\{start|stop|status\\}" end end
Save function permanently¶
funcsave greet funcsave calculate_sum ```_
Fehlerbehebung¶
```fish
Function with error handling¶
function safe_copy --description "Safe file copy with error handling" if test (count $argv) -ne 2 echo "Error: Exactly two arguments required" >&2 return 1 end
set -l source $argv[1]
set -l dest $argv[2]
if not test -f "$source"
echo "Error: Source file '$source' does not exist" >&2
return 1
end
if test -f "$dest"
echo "Warning: Destination file '$dest' already exists"
read -P "Overwrite? (y/N): " -l confirm
if test "$confirm" != "y"
echo "Copy cancelled"
return 1
end
end
if cp "$source" "$dest"
echo "Successfully copied '$source' to '$dest'"
else
echo "Error: Failed to copy file" >&2
return 1
end
end ```_
Interaktive Funktionen¶
Autosuggestions¶
```fish
Autosuggestions are enabled by default¶
Type a command and Fish will suggest completions based on:¶
- Command history¶
- Valid file paths¶
- Command completions¶
Accept suggestion: Right arrow or Ctrl+F¶
Accept single word: Alt+Right arrow or Alt+F¶
Dismiss suggestion: Escape¶
Configure autosuggestion color¶
set -g fish_color_autosuggestion 555 ```_
Tab Fertigkeiten¶
```fish
Tab completions work automatically for:¶
- Commands in PATH¶
- File and directory names¶
- Command-specific options and arguments¶
Custom completion for your function¶
complete -c mycommand -a "start stop status restart" -d "Service commands" complete -c mycommand -s h -l help -d "Show help" complete -c mycommand -s v -l verbose -d "Verbose output"
File-based completion¶
complete -c myapp -a "(__fish_complete_suffix .conf)" -d "Configuration files"
Conditional completion¶
complete -c git -n "__fish_git_needs_command" -a "add commit push pull" complete -c git -n "__fish_git_using_command add" -a "(__fish_git_modified_files)" ```_
Syntax Highlights¶
```fish
Syntax highlighting is automatic and includes:¶
- Valid/invalid commands (green/red)¶
- Strings and quotes¶
- Variables and expansions¶
- Comments¶
Customize syntax highlighting colors¶
set -g fish_color_command blue set -g fish_color_param cyan set -g fish_color_redirection yellow set -g fish_color_comment brblack set -g fish_color_error red set -g fish_color_escape bryellow set -g fish_color_operator green set -g fish_color_quote yellow set -g fish_color_valid_path --underline ```_
Geschichte und Suche¶
```fish
History search (automatic)¶
Type partial command and use Up/Down arrows¶
History search with specific text¶
Type text and press Ctrl+R for reverse search¶
History commands¶
history # Show all history history search "git" # Search history for "git" history delete --prefix "rm" # Delete commands starting with "rm" history clear # Clear all history
Configure history¶
set -g fish_history_max 10000 # Maximum history entries ```_
Konfiguration und Anpassung¶
Umweltvariablen¶
```fish
Set environment variables¶
set -gx EDITOR vim set -gx BROWSER firefox set -gx PAGER less
PATH manipulation¶
set -gx PATH $HOME/bin $PATH set -gx PATH $HOME/.local/bin $PATH set -gx PATH /usr/local/bin $PATH
Remove from PATH¶
set -l index (contains -i /unwanted/path $PATH) if test \(index -gt 0 set -e PATH[\)index] end
Conditional environment variables¶
if test -d "$HOME/.cargo/bin" set -gx PATH $HOME/.cargo/bin $PATH end
Platform-specific variables¶
switch (uname) case Darwin set -gx HOMEBREW_PREFIX /opt/homebrew case Linux set -gx XDG_CONFIG_HOME $HOME/.config end ```_
Alias und Abkürzungen¶
```fish
Aliases (expanded when defined)¶
alias ll 'ls -alF' alias la 'ls -A' alias l 'ls -CF' alias grep 'grep --color=auto'
Abbreviations (expanded when typed)¶
abbr -a g git abbr -a gc 'git commit' abbr -a gp 'git push' abbr -a gl 'git log --oneline' abbr -a gst 'git status'
Conditional abbreviations¶
if command -v docker >/dev/null abbr -a d docker abbr -a dc 'docker-compose' abbr -a dps 'docker ps' end
List and manage abbreviations¶
abbr -l # List all abbreviations abbr -e gc # Erase abbreviation ```_
Prompt Anpassung¶
```fish
Simple prompt function¶
function fish_prompt set_color green echo -n (whoami) set_color normal echo -n "@" set_color blue echo -n (hostname) set_color normal echo -n ":" set_color yellow echo -n (prompt_pwd) set_color normal echo -n "$ " end
Advanced prompt with Git integration¶
function fish_prompt set -l last_status $status
# User and host
set_color green
echo -n (whoami)
set_color normal
echo -n "@"
set_color blue
echo -n (hostname)
set_color normal
# Current directory
echo -n ":"
set_color yellow
echo -n (prompt_pwd)
set_color normal
# Git information
if git rev-parse --git-dir >/dev/null 2>&1
set -l branch (git branch --show-current 2>/dev/null)
if test -n "$branch"
echo -n " ("
set_color cyan
echo -n "$branch"
set_color normal
# Check for changes
if not git diff --quiet 2>/dev/null
set_color red
echo -n "*"
set_color normal
end
echo -n ")"
end
end
# Prompt symbol based on last command status
if test $last_status -eq 0
set_color green
echo -n " ❯ "
else
set_color red
echo -n " ❯ "
end
set_color normal
end
Right prompt¶
function fish_right_prompt set_color brblack echo -n (date "+%H:%M:%S") set_color normal end ```_
Thema und Farbkonfiguration¶
```fish
Use fish_config for GUI configuration¶
fish_config
Or set colors manually¶
set -g fish_color_normal normal set -g fish_color_command blue set -g fish_color_quote yellow set -g fish_color_redirection cyan set -g fish_color_end green set -g fish_color_error red set -g fish_color_param cyan set -g fish_color_comment brblack set -g fish_color_match --background=brblue set -g fish_color_selection white --bold --background=brblack set -g fish_color_search_match bryellow --background=brblack set -g fish_color_history_current --bold set -g fish_color_operator green set -g fish_color_escape bryellow set -g fish_color_cwd green set -g fish_color_cwd_root red set -g fish_color_valid_path --underline set -g fish_color_autosuggestion 555 set -g fish_color_user brgreen set -g fish_color_host normal set -g fish_color_cancel -r set -g fish_pager_color_completion normal set -g fish_pager_color_description B3A06D yellow set -g fish_pager_color_prefix white --bold --underline set -g fish_pager_color_progress brwhite --background=cyan ```_
Paketverwaltung und Plugins¶
Fisher Plugin Manager¶
```fish
Install Fisher¶
curl -sL https://git.io/fisher|source && fisher install jorgebucaran/fisher
Install plugins¶
fisher install jorgebucaran/nvm.fish fisher install PatrickF1/fzf.fish fisher install franciscolourenco/done fisher install jethrokuan/z
List installed plugins¶
fisher list
Update plugins¶
fisher update
Remove plugin¶
fisher remove jorgebucaran/nvm.fish ```_
Beliebte Fisch Plugins¶
```fish
z - Directory jumping¶
fisher install jethrokuan/z
Usage: z partial_directory_name¶
fzf integration¶
fisher install PatrickF1/fzf.fish
Provides Ctrl+R for history search, Ctrl+Alt+F for file search¶
done - Desktop notifications¶
fisher install franciscolourenco/done
Notifies when long-running commands complete¶
nvm for Node.js¶
fisher install jorgebucaran/nvm.fish nvm install node nvm use node
autopair - Automatic bracket pairing¶
fisher install jorgebucaran/autopair.fish
bass - Run Bash utilities in Fish¶
fisher install edc/bass bass source ~/.bashrc ```_
Manuelle Plugin Installation¶
```fish
Create functions directory¶
mkdir -p ~/.config/fish/functions
Download and install plugin manually¶
curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
Install from local directory¶
git clone https://github.com/user/plugin.git cp plugin/*.fish ~/.config/fish/functions/ ```_
Erweiterte Funktionen und Tipps¶
Mathematik¶
```fish
Math command for calculations¶
math 5 + 3 # 8 math 10 * 2 # 20 (escape * in some contexts) math "10 * 2" # 20 math 20 / 4 # 5 math 17 % 5 # 2
Math with variables¶
set num1 10 set num2 5 math $num1 + $num2 # 15
Advanced math functions¶
math "sqrt(16)" # 4 math "sin(3.14159/2)" # 1 math "log(10)" # 2.30259 math "pow(2, 8)" # 256
Floating point precision¶
math -s2 10 / 3 # 3.33 (2 decimal places) ```_
Dateioperationen und Globbing¶
```fish
Basic globbing¶
ls .txt # All .txt files ls **/.py # All .py files recursively ls file?.txt # file1.txt, file2.txt, etc.
Advanced globbing patterns¶
ls *.(txt|md|rst) # Files with specific extensions ls file[1-9].txt # file1.txt through file9.txt
File test operations¶
if test -f "file.txt" echo "File exists" end
if test -d "directory" echo "Directory exists" end
if test -x "script.sh" echo "File is executable" end
File manipulation¶
cp source.txt destination.txt mv old_name.txt new_name.txt rm unwanted_file.txt mkdir new_directory rmdir empty_directory ```_
Prozessmanagement¶
```fish
Background jobs¶
command & # Run in background jobs # List active jobs fg %1 # Bring job 1 to foreground bg %1 # Send job 1 to background kill %1 # Kill job 1
Process information¶
ps aux # List all processes pgrep firefox # Find process by name pkill firefox # Kill process by name
Disown processes¶
command & disown # Detach from shell ```_
Input/Output-Umleitung¶
```fish
Output redirection¶
command > file.txt # Redirect stdout to file command >> file.txt # Append stdout to file command 2> error.log # Redirect stderr to file command &> output.log # Redirect both stdout and stderr
Input redirection¶
command < input.txt # Read input from file
Pipes¶
ls -l|grep "txt" # Pipe output to grep ps aux|grep "firefox"|wc -l # Count firefox processes
Tee command¶
command|tee file.txt # Write to file and stdout ```_
Best Practices Scripting¶
Schriftstruktur¶
```fish
!/usr/bin/env fish¶
Script description¶
Author: Your Name¶
Date: YYYY-MM-DD¶
Function definitions¶
function usage echo "Usage: $argv[0]
function main # Parse arguments argparse 'h/help' 'v/verbose' -- $argv or return
if set -q _flag_help
usage
return 0
end
if set -q _flag_verbose
set -g verbose true
end
# Main script logic here
echo "Script execution completed"
end
Call main function with all arguments¶
main $argv ```_
Fehlerbehebung¶
```fish
Check command success¶
if command_that_might_fail echo "Command succeeded" else echo "Command failed with status $status" exit 1 end
Validate arguments¶
function validate_file set -l file \(argv[1] if not test -f "\)file" echo "Error: File '$file' does not exist" >&2 return 1 end return 0 end
Use in script¶
if not validate_file "important.txt" exit 1 end ```_
Leistungsbetrachtungen¶
```fish
Use built-in string operations instead of external commands¶
set result (string replace "old" "new" $text) # Instead of sed set length (string length $text) # Instead of wc
Avoid unnecessary command substitutions¶
if test -f "file.txt" # Instead of if test (ls file.txt) echo "File exists" end
Use arrays efficiently¶
set files *.txt for file in $files # Instead of for file in (ls *.txt) process_file $file end ```_
Debugging und Fehlerbehebung¶
Debug Mode¶
```fish
Run script with debug output¶
fish -d 3 script.fish
Enable debug in script¶
set fish_trace 1
Your commands here¶
set fish_trace 0
Function debugging¶
function debug_function echo "Function called with arguments: $argv" >&2 echo "Current directory: "(pwd) >&2 echo "Status: $status" >&2 end ```_
Gemeinsame Themen und Lösungen¶
```fish
Issue: Command not found¶
Solution: Check PATH and command existence¶
if not command -v mycommand >/dev/null echo "mycommand is not installed or not in PATH" exit 1 end
Issue: Variable not expanding¶
Solution: Use proper Fish syntax¶
set var "value" echo \(var # Correct echo "\)var" # Also correct echo '$var' # Wrong - literal string
Issue: Function not found¶
Solution: Check function definition and loading¶
functions myfunction # Check if function exists funcsave myfunction # Save function permanently ```_
Leistungsprofil¶
```fish
Time command execution¶
time command
Profile function execution¶
function profile_function set -l start_time (date +%s%N) your_function \(argv set -l end_time (date +%s%N) set -l duration (math "(\)end_time - $start_time) / 1000000") echo "Function took $duration ms" end ```_
Fish Shell stellt eine Paradigmenverschiebung in der Shell-Design, Priorisierung der Benutzererfahrung und Entdeckbarkeit über strenge POSIX-Compliance. Seine intelligente Autovorschläge, Syntax-Highlighting und webbasierte Konfiguration machen es besonders attraktiv für Neuankömmlinge in der Kommandozeile, während seine leistungsstarken Skripting-Funktionen und umfangreiches Plugin-Ökosystem den Bedürfnissen von fortgeschrittenen Benutzern gerecht werden. Obwohl seine unterschiedliche Syntax einige Anpassungen für Benutzer erfordert, die von traditionellen Shells kommen, macht Fish den Fokus darauf, hilfreich und intuitiv zu sein, eine ausgezeichnete Wahl für interaktive Shell-Nutzung und moderne Entwicklungs-Workflows.