10 KiB
obj | website | repo |
---|---|---|
application | https://fishshell.com | https://github.com/fish-shell/fish-shell |
fish
fish is a smart and user-friendly command line shell for Linux, macOS, and the rest of the family.
Usage
Abbreviations
To avoid needless typing, a frequently-run command like git checkout
can be abbreviated to gco
using the abbr
command.
abbr -a gco git checkout
After entering gco
and pressing space or enter, a gco
in command position will turn into git checkout
in the command line. If you want to use a literal gco
sometimes, use ctrl-space
.
Abbreviations are a lot more powerful than just replacing literal strings. For example you can make going up a number of directories easier with this:
function multicd
echo cd (string repeat -n (math (string length -- $argv[1]) - 1) ../)
end
abbr --add dotdot --regex '^\.\.+$' --function multicd
Now, ..
transforms to cd ../
, while ...
turns into cd ../../
and ....
expands to cd ../../../
.
The advantage over aliases is that you can see the actual command before using it, add to it or change it, and the actual command will be stored in history.
Custom bindings
In addition to the standard bindings listed here, you can also define your own with bind
:
# Just clear the commandline on control-c
bind ctrl-c 'commandline -r ""'
Put bind
statements into config.fish
or a function called fish_user_key_bindings
.
If you change your mind on a binding and want to go back to fish’s default, you can simply erase it again:
bind --erase ctrl-c
History
After a command has been executed, it is remembered in the history list. Any duplicate history items are automatically removed. By pressing the up and down keys, you can search forwards and backwards in the history. If the current command line is not empty when starting a history search, only the commands containing the string entered into the command line are shown.
By pressing alt-up
(↑
) and alt-down
(↓
), a history search is also performed, but instead of searching for a complete commandline, each commandline is broken into separate elements just like it would be before execution, and the history is searched for an element matching that under the cursor.
For more complicated searches, you can press ctrl-r
to open a pager that allows you to search the history. It shows a limited number of entries in one page, press ctrl-r
again to move to the next page and ctrl-s
to move to the previous page. You can change the text to refine your search.
History searches are case-insensitive unless the search string contains an uppercase character. You can stop a search to edit your search string by pressing escape
or pagedown
.
Prefixing the commandline with a space will prevent the entire line from being stored in the history. It will still be available for recall until the next command is executed, but will not be stored on disk. This is to allow you to fix misspellings and such.
The command history is stored in the file ~/.local/share/fish/fish_history
(or $XDG_DATA_HOME/fish/fish_history
if that variable is set) by default. However, you can set the fish_history
environment variable to change the name of the history session (resulting in a <session>_history
file); both before starting the shell and while the shell is running.
See the history
command for other manipulations.
Private mode
Fish has a private mode, in which command history will not be written to the history file on disk. To enable it, either set $fish_private_mode
to a non-empty value, or launch with fish --private
(or fish -P
for short).
If you launch fish with -P
, it both hides old history and prevents writing history to disk. This is useful to avoid leaking personal information (e.g. for screencasts) or when dealing with sensitive information.
You can query the variable fish_private_mode (if test -n "$fish_private_mode" ...)
if you would like to respect the user’s wish for privacy and alter the behavior of your own fish scripts.
Directory History
Navigating directories is usually done with the cd
command, but fish offers some advanced features as well.
The current working directory can be displayed with the pwd
command, or the $PWD
special variable. Usually your prompt already does this.
Fish automatically keeps a trail of the recent visited directories with cd
by storing this history in the dirprev
and dirnext
variables.
Several commands are provided to interact with this directory history:
dirh
prints the historycdh
displays a prompt to quickly navigate the historyprevd
moves backward through the history. It is bound toalt-left
(←
)nextd
moves forward through the history. It is bound toalt-right
(→
)
Configuration
To store configuration write it to a file called ~/.config/fish/config.fish
.
.fish
scripts in ~/.config/fish/conf.d/
are also automatically executed before config.fish
.
These files are read on the startup of every shell, whether interactive and/or if they’re login shells. Use status --is-interactive
and status --is-login
to do things only in interactive/login shells, respectively.
Shell Scripting
Shebang
Because shell scripts are written in many different languages, they need to carry information about which interpreter should be used to execute them. For this, they are expected to have a first line, the shebang line, which names the interpreter executable.
A script written in bash would need a first line like this:
#!/bin/bash
When the shell tells the kernel to execute the file, it will use the interpreter /bin/bash
.
For a script written in another language, just replace /bin/bash
with the interpreter for that language. For example: /usr/bin/python
for a python script, or /usr/local/bin/fish
for a fish script, if that is where you have them installed.
If you want to share your script with others, you might want to use env to allow for the interpreter to be installed in other locations. For example:
#!/usr/bin/env fish
echo Hello from fish $version
This will call env
, which then goes through PATH
to find a program called “fish”. This makes it work, whether fish is installed in (for example) /usr/local/bin/fish
, /usr/bin/fish
, or ~/.local/bin/fish
, as long as that directory is in PATH
.
The shebang line is only used when scripts are executed without specifying the interpreter. For functions inside fish or when executing a script with fish /path/to/script
, a shebang is not required (but it doesn’t hurt!).
When executing files without an interpreter, fish, like other shells, tries your system shell, typically /bin/sh
. This is needed because some scripts are shipped without a shebang line.
Variables
In Fish, variables are assigned using the set
command:
set name "Alice"
set -g global_var "I'm global"
set -x PATH $PATH /custom/bin # export variable to child processes
-g
: Sets a global variable.-x
: Exports the variable.- Arrays are space-separated:
set colors red green blue
echo $colors[1] # Outputs: red
Conditionals
Fish uses if
, else if
, and else
:
set age 20
if test $age -ge 18
echo "You're an adult"
else if test $age -ge 13
echo "You're a teenager"
else
echo "You're a child"
end
Switch Statements
Use switch
for cleaner branching with string values:
set lang "rust"
switch $lang
case rust
echo "You're using Rust!"
case python
echo "Python is cool too."
case '*'
echo "Unknown language"
end
Loops
for
Loop
for color in red green blue
echo $color
end
while
Loop
set count 1
while test $count -le 3
echo "Count: $count"
set count (math $count + 1)
end
Functions
Define reusable blocks of code with function
:
function greet
echo "Hello, $argv"
end
greet "World" # Output: Hello, World
$argv
holds all passed arguments.$argv[1]
is the first argument.
Returning Values
Functions can return more than just a status code. They can return actual output:
function get_username
echo "alice"
end
set user (get_username)
echo $user # Outputs: alice
For status codes, use return
:
function is_even
if test (math "$argv[1] % 2") -eq 0
return 0
else
return 1
end
end
Events
Fish supports event-driven scripting using functions --on-event
:
function notify_start --on-event fish_prompt
echo "Shell is ready!"
end
Events can be fired with the emit
command, and do not have to be defined before. The names just need to match. For example:
function handler --on-event imdone
echo generator is done $argv
end
function generator
sleep 1
# The "imdone" is the name of the event
# the rest is the arguments to pass to the handler
emit imdone with $argv
end
Tools
Builtins to do a task, like
cd
to change the current directory.echo
orprintf
to produce output.set_color
to colorize output.set
to set, query or erase variables.read
to read input.string
for string manipulation.path
for filtering paths and handling their components.math
does arithmetic.argparse
to make arguments easier to handle.count
to count arguments.type
to find out what sort of thing (command, builtin or function) fish would call, or if it exists at all.test
checks conditions like if a file exists or a string is empty.contains
to see if a list contains an entry.eval
andsource
to run fish code from a string or file.status
to get shell information, like whether it’s interactive or a login shell, or which file it is currently running.abbr
manages Abbreviations.bind
to change bindings.complete
manages completions.commandline
to get or change the commandline contents.fish_config
to easily change fish’s configuration, like the prompt or colorscheme.random
to generate random numbers or pick from a list.