---
obj: application
website: https://fishshell.com
repo: 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:

```fish
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 history
- `cdh` displays a prompt to quickly navigate the history
- `prevd` moves backward through the history. It is bound to `alt-left` (`←`)
- `nextd` moves forward through the history. It is bound to `alt-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`](https://fishshell.com/docs/current/language.html#envvar-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`](https://fishshell.com/docs/current/language.html#envvar-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:

```fish
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:

```fish
set colors red green blue
echo $colors[1]  # Outputs: red
```

### Conditionals

Fish uses `if`, `else if`, and `else`:

```fish
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:

```fish
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

```fish
for color in red green blue
    echo $color
end
```

#### `while` Loop

```fish
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`:

```fish
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:

```fish
function get_username
    echo "alice"
end

set user (get_username)
echo $user  # Outputs: alice
```

For status codes, use `return`:

```fish
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`:

```fish
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:

```fish
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` or `printf` 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` and `source` 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.
