--- 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 `_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.