Fish - Shell Interattivo Amichevole¶
Fish (Friendly Interactive Shell) è un shell a riga di comando intelligente e user-friendly progettato per l'uso interattivo, l'usabilità e la scopribilità. Creato da Axel Liljencrantz nel 2005, Fish adotta un approccio diverso rispetto agli shell tradizionali, dando priorità all'esperienza utente e fornendo impostazioni predefinite sensibili fin da subito. A differenza degli shell conformi a POSIX, Fish offre evidenziazione della sintassi, suggerimenti automatici, completamenti con tab che funzionano senza configurazione, e una sintassi pulita e moderna che mira a essere più intuitiva e meno soggetta a errori rispetto ai linguaggi shell tradizionali.
Installazione e Configurazione¶
Installazione di Fish Shell¶
# 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
Impostare Fish come Shell Predefinito¶
# 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
Configurazione Iniziale¶
# 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
Struttura Base della Configurazione¶
# 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
Sintassi e Caratteristiche del Linguaggio Fish¶
Variabili e Scope¶
# 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
Sostituzione di Comandi¶
# 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
Manipolazione delle Stringhe¶
# 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
Istruzioni Condizionali¶
# 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
Cicli e Iterazione¶
# 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
Funzioni e Scripting¶
Definizione di Funzioni¶
# 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 <num1> <num2>"
return 1
end
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
Funzionalità Avanzate delle Funzioni¶
# 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
Gestione degli Errori¶
# 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
Funzionalità Interattive¶
Suggerimenti Automatici¶
# 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
Completamenti con Tab¶
# 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)"
Evidenziazione della Sintassi¶
# 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
Cronologia e Ricerca¶
# 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
Configurazione e Personalizzazione¶
Variabili di Ambiente¶
# 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 e Abbreviazioni¶
# 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
Personalizzazione del Prompt¶
Would you like me to continue with the remaining sections?```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
### Configurazione del Tema e dei Colorifish
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 ```## Gestione dei Pacchetti e Plugin
Gestore di Plugin Fisher¶
```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
### Plugin Fish Popolarifish
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
### Installazione Manuale di Pluginfish
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/ ```## Funzionalità Avanzate e Suggerimenti
Operazioni Matematiche¶
```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)
### Operazioni sui File e Globbingfish
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
### Gestione dei Processifish
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
### Reindirizzamento Input/Outputfish
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 ```## Migliori Pratiche di Scripting
Struttura dello Script¶
```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
### Gestione degli Errorifish
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
### Considerazioni sulle Prestazionifish
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 ```## Debug e Risoluzione dei Problemi
Modalità Debug¶
```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
### Problemi Comuni e Soluzionifish
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
### Profilazione delle Prestazionifish
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 rappresenta un cambiamento di paradigma nel design delle shell, dando priorità all'esperienza utente e alla scoperta rispetto alla stretta conformità POSIX. I suoi suggerimenti intelligenti, l'evidenziazione della sintassi e la configurazione basata sul web lo rendono particolarmente attraente per i nuovi utenti della riga di comando, mentre le sue potenti capacità di scripting e l'ampio ecosistema di plugin soddisfano le esigenze degli utenti avanzati. Sebbene la sua sintassi diversa richieda un certo adattamento per gli utenti provenienti da shell tradizionali, l'attenzione di Fish verso l'essere utile e intuitivo lo rende un'eccellente scelta per l'uso interattivo della shell e per i flussi di lavoro di sviluppo moderni.