2014-08-08 10:44:37 +08:00
/**
\page tutorial Tutorial
2014-08-01 10:37:32 +08:00
\htmlonly[block]
<div class="fish_left_bar">
2014-08-30 18:03:02 +08:00
<div class="logo"></div>
2014-08-01 10:37:32 +08:00
<div class="menu tutorial_menu">
\endhtmlonly
- <a href="#tut_why_fish">Why fish?</a>
2018-06-04 16:10:01 +08:00
- <a href="#tut_getting_started">Getting started</a>
2014-08-01 10:37:32 +08:00
- <a href="#tut_learning_Fish">Learning fish</a>
- <a href="#tut_running_commands">Running Commands</a>
- <a href="#tut_getting_help">Getting Help</a>
- <a href="#tut_syntax_highlighting">Syntax Highlighting</a>
- <a href="#tut_wildcards">Wildcards</a>
- <a href="#tut_pipes_and_redirections">Pipes and Redirections</a>
- <a href="#tut_autosuggestions">Autosuggestions</a>
- <a href="#tut_tab_completions">Tab Completions</a>
- <a href="#tut_variables">Variables</a>
- <a href="#tut_exit_status">Exit Status</a>
- <a href="#tut_exports">Shell Variables</a>
- <a href="#tut_lists">Lists</a>
- <a href="#tut_command_substitutions">Command Substitutions</a>
2017-06-11 19:45:52 +08:00
- <a href="#tut_semicolon">Separating Commands (Semicolon)</a>
2014-08-01 10:37:32 +08:00
- <a href="#tut_combiners">Combiners (And, Or, Not)</a>
- <a href="#tut_conditionals">Conditionals (If, Else, Switch)</a>
- <a href="#tut_functions">Functions</a>
- <a href="#tut_loops">Loops</a>
- <a href="#tut_prompt">Prompt</a>
2014-08-08 10:44:37 +08:00
- <a href="#tut_path">$PATH</a>
2014-08-01 10:37:32 +08:00
- <a href="#tut_startup">Startup</a>
2014-08-08 10:44:37 +08:00
- <a href="#tut_autoload">Autoloading Functions</a>
2016-03-22 06:52:11 +08:00
- <a href="#tut_universal">Universal Variables</a>
2018-06-04 16:10:01 +08:00
- <a href="#tut_switching_to_fish">Switching to fish</a>
2015-07-04 03:35:53 +08:00
- <a href="#tut_more">Ready for more?</a>
2014-08-01 10:37:32 +08:00
\htmlonly[block]
</div>
2013-10-05 15:37:44 +08:00
</div>
2014-08-01 10:37:32 +08:00
<div class="tutorial fish_right_bar">
2013-10-05 15:37:44 +08:00
<h1 class="interior_title">fish tutorial</h1>
2014-08-01 10:37:32 +08:00
\endhtmlonly
\section tut_why_fish Why fish?
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
`fish` is a fully-equipped command line shell (like bash or zsh) that is smart and user-friendly. `fish` supports powerful features like syntax highlighting, autosuggestions, and tab completions that just work, with nothing to learn or configure.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
If you want to make your command line more productive, more useful, and more fun, without learning a bunch of arcane syntax and configuration options, then `fish` might be just what you're looking for!
2013-10-05 15:37:44 +08:00
2018-06-04 16:10:01 +08:00
\section tut_getting_started Getting started
2013-10-05 15:37:44 +08:00
2018-06-04 16:10:01 +08:00
Once installed, just type in `fish` into your current shell to try it out!
2013-10-05 15:37:44 +08:00
2018-06-04 16:10:01 +08:00
You will be greeted by the standard fish prompt,
which means you are all set up and can start using fish:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2018-06-04 16:10:01 +08:00
> fish
2016-07-16 18:27:02 +08:00
<outp>Welcome to fish, the friendly interactive shell</outp>
<outp>Type <span class="cwd">help</span> for instructions on how to use fish</outp>
<asis>you@hostname</asis> ~>____
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2018-06-04 16:10:01 +08:00
This prompt that you see above is the `fish` default prompt: it shows your username, hostname, and working directory.
- to change this prompt see <a href="#tut_prompt">how to change your prompt</a>
- to switch to fish permanently see <a href="#tut_switching_to_fish">switch your default shell to fish</a>
From now on, we'll pretend your prompt is just a '`>`' to save space.
\section tut_learning_Fish Learning fish
This tutorial assumes a basic understanding of command line shells and Unix commands, and that you have a working copy of `fish`.
If you have a strong understanding of other shells, and want to know what `fish` does differently, search for the magic phrase <em>unlike other shells</em>, which is used to call out important differences.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_running_commands Running Commands
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
`fish` runs commands like other shells: you type a command, followed by its arguments. Spaces are separators:
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo hello world
2016-07-16 18:27:02 +08:00
<outp>hello world</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
You can include a literal space in an argument with a backslash, or by using single or double quotes:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ mkdir My\ Files
>_ cp ~/Some\ File 'My Files'
>_ ls "My Files"
2016-07-16 18:27:02 +08:00
<outp>Some File</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
Commands can be chained with semicolons.
2014-08-01 10:37:32 +08:00
\section tut_getting_help Getting Help
`fish` has excellent help and man pages. Run `help` to open help in a web browser, and `man` to open it in a man page. You can also ask for help with a specific command, for example, `help set` to open in a web browser, or `man set` to see it in the terminal.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ man set
2016-07-16 18:27:02 +08:00
<outp>set - handle shell variables</outp>
<outp> Synopsis...</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_syntax_highlighting Syntax Highlighting
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
You'll quickly notice that `fish` performs syntax highlighting as you type. Invalid commands are colored red by default:
\fish{cli-dark}
2016-07-16 18:27:02 +08:00
>_ <eror>/bin/mkd</eror>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
A command may be invalid because it does not exist, or refers to a file that you cannot execute. When the command becomes valid, it is shown in a different color:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ /bin/mkdir
2014-08-01 10:37:32 +08:00
\endfish
`fish` will underline valid file paths as you type them:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2016-07-16 18:27:02 +08:00
>_ cat <u>~/somefi</u>___
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
This tells you that there exists a file that starts with '`somefi`', which is useful feedback as you type.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
These colors, and many more, can be changed by running `fish_config`, or by modifying variables directly.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_wildcards Wildcards
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
`fish` supports the familiar wildcard `*`. To list all JPEG files:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ ls *.jpg
2016-07-16 18:27:02 +08:00
<outp>lena.jpg</outp>
<outp>meena.jpg</outp>
<outp>santa maria.jpg</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
You can include multiple wildcards:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ ls l*.p*
2016-07-16 18:27:02 +08:00
<outp>lena.png</outp>
<outp>lesson.pdf</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
Especially powerful is the recursive wildcard ** which searches directories recursively:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ ls /var/**.log
2016-07-16 18:27:02 +08:00
<outp>/var/log/system.log</outp>
<outp>/var/run/sntp.log</outp>
2014-08-01 10:37:32 +08:00
\endfish
If that directory traversal is taking a long time, you can @key{Control,C} out of it.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_pipes_and_redirections Pipes and Redirections
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
You can pipe between commands with the usual vertical bar:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo hello world | wc
2016-07-16 18:27:02 +08:00
<outp> 1 2 12</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2019-02-10 01:48:38 +08:00
stdin and stdout can be redirected via the familiar < and >. stderr is redirected with a >2.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2019-02-10 01:48:38 +08:00
>_ grep fish < /etc/shells > ~/output.txt 2> ~/errors.txt
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_autosuggestions Autosuggestions
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
`fish` suggests commands as you type, and shows the suggestion to the right of the cursor, in gray. For example:
\fish{cli-dark}
2016-07-16 18:27:02 +08:00
>_ <eror>/bin/h</eror><s>___ostname</s>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
It knows about paths and options:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2016-07-16 18:27:02 +08:00
>_ grep --i<s>___gnore-case</s>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
And history too. Type a command once, and you can re-summon it by just typing a few letters:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2016-07-16 18:27:02 +08:00
>_ <eror>r<</eror><s>___sync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo</s>
2014-08-01 10:37:32 +08:00
\endfish
2014-09-12 21:25:21 +08:00
To accept the autosuggestion, hit @cursor_key{→,right arrow} or @key{Control,F}. To accept a single word of the autosuggestion, @key{Alt,→} (right arrow). If the autosuggestion is not what you want, just ignore it.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_tab_completions Tab Completions
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
`fish` comes with a rich set of tab completions, that work "out of the box."
2013-10-05 15:37:44 +08:00
2014-09-12 21:25:21 +08:00
Press @key{Tab}, and `fish` will attempt to complete the command, argument, or path:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2016-07-16 18:27:02 +08:00
>_ <eror>/pri</eror> @key{Tab} → /private/
2014-08-01 10:37:32 +08:00
\endfish
If there's more than one possibility, it will list them:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2016-07-16 18:27:02 +08:00
>_ <eror>~/stuff/s</eror> @key{Tab}
<outp><mtch>~/stuff/s</outp>cript.sh <i>(Executable, 4.8kB)</i> \mtch{~/stuff/s</mtch>ources/ <i>(Directory)</i>}
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Hit tab again to cycle through the possibilities.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
`fish` can also complete many commands, like git branches:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ git merge pr @key{Tab} → git merge prompt_designer
>_ git checkout b @key{Tab}
2016-07-16 18:27:02 +08:00
<outp><mtch>b</outp>uiltin_list_io_merge <i>(Branch)</i> \mtch{b</mtch>uiltin_set_color <i>(Branch)</i> <mtch>b</mtch>usted_events <i>(Tag)</i>}
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Try hitting tab and see what `fish` can do!
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_variables Variables
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
Like other shells, a dollar sign performs variable substitution:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo My home directory is $HOME
2016-07-16 18:27:02 +08:00
<outp>My home directory is /home/tutorial</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
Variable substitution also occurs in double quotes, but not single quotes:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo "My current directory is $PWD"
2016-07-16 18:27:02 +08:00
<outp>My current directory is /home/tutorial</outp>
2014-08-08 10:44:37 +08:00
>_ echo 'My current directory is $PWD'
2016-07-16 18:27:02 +08:00
<outp>My current directory is $PWD</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Unlike other shells, `fish` has no dedicated syntax for setting variables. Instead it has an ordinary command: `set`, which takes a variable name, and then its value.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ set name 'Mister Noodle'
>_ echo $name
2016-07-16 18:27:02 +08:00
<outp>Mister Noodle</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
(Notice the quotes: without them, `Mister` and `Noodle` would have been separate arguments, and `$name` would have been made into a list of two elements.)
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
Unlike other shells, variables are not further split after substitution:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ mkdir $name
>_ ls
2016-07-16 18:27:02 +08:00
<outp>Mister Noodle</outp>
2014-08-01 10:37:32 +08:00
\endfish
2015-07-23 18:43:57 +08:00
In bash, this would have created two directories "Mister" and "Noodle". In `fish`, it created only one: the variable had the value "Mister Noodle", so that is the argument that was passed to `mkdir`, spaces and all. Other shells use the term "arrays", rather than lists.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_exit_status Exit Status
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Unlike other shells, `fish` stores the exit status of the last command in `$status` instead of `$?`.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ false
>_ echo $status
2016-07-16 18:27:02 +08:00
<outp>1</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
Zero is considered success, and non-zero is failure.
2014-08-08 10:44:37 +08:00
\section tut_exports Exports (Shell Variables)
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Unlike other shells, `fish` does not have an export command. Instead, a variable is exported via an option to `set`, either `--export` or just `-x`.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ set -x MyVariable SomeValue
>_ env | grep MyVariable
2017-11-06 20:35:35 +08:00
<outp><m>MyVariable</outp>=SomeValue</m>
2014-08-01 10:37:32 +08:00
\endfish
You can erase a variable with `-e` or `--erase`
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ set -e MyVariable
>_ env | grep MyVariable
2016-07-16 18:27:02 +08:00
<outp>(no output)</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_lists Lists
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
The `set` command above used quotes to ensure that `Mister Noodle` was one argument. If it had been two arguments, then `name` would have been a list of length 2. In fact, all variables in `fish` are really lists, that can contain any number of values, or none at all.
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
Some variables, like `$PWD`, only have one value. By convention, we talk about that variable's value, but we really mean its first (and only) value.
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
Other variables, like `$PATH`, really do have multiple values. During variable expansion, the variable expands to become multiple arguments:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo $PATH
2016-07-16 18:27:02 +08:00
<outp>/usr/bin /bin /usr/sbin /sbin /usr/local/bin</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2017-05-26 12:11:51 +08:00
Note that there are three environment variables that are automatically split on colons to become lists when fish starts running: `PATH`, `CDPATH`, `MANPATH`. Conversely, they are joined on colons when exported to subcommands. All other environment variables (e.g., `LD_LIBRARY_PATH`) which have similar semantics are treated as simple strings.
2014-08-01 10:37:32 +08:00
Lists cannot contain other lists: there is no recursion. A variable is a list of strings, full stop.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Get the length of a list with `count`:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ count $PATH
2016-07-16 18:27:02 +08:00
<outp>5</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
You can append (or prepend) to a list by setting the list to itself, with some additional arguments. Here we append /usr/local/bin to $PATH:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ set PATH $PATH /usr/local/bin
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
You can access individual elements with square brackets. Indexing starts at 1 from the beginning, and -1 from the end:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo $PATH
2016-07-16 18:27:02 +08:00
<outp>/usr/bin /bin /usr/sbin /sbin /usr/local/bin</outp>
2014-08-08 10:44:37 +08:00
>_ echo $PATH[1]
2016-07-16 18:27:02 +08:00
<outp>/usr/bin</outp>
2014-08-08 10:44:37 +08:00
>_ echo $PATH[-1]
2016-07-16 18:27:02 +08:00
<outp>/usr/local/bin</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
You can also access ranges of elements, known as "slices:"
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo $PATH[1..2]
2016-07-16 18:27:02 +08:00
<outp>/usr/bin /bin</outp>
2014-08-08 10:44:37 +08:00
>_ echo $PATH[-1..2]
2016-07-16 18:27:02 +08:00
<outp>/usr/local/bin /sbin /usr/sbin /bin</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
You can iterate over a list (or a slice) with a for loop:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ for val in $PATH
echo "entry: $val"
end
2016-07-16 18:27:02 +08:00
<outp>entry: /usr/bin/</outp>
<outp>entry: /bin</outp>
<outp>entry: /usr/sbin</outp>
<outp>entry: /sbin</outp>
<outp>entry: /usr/local/bin</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2015-12-14 01:27:33 +08:00
Lists adjacent to other lists or strings are expanded as <a href="index.html#cartesian-product">cartesian products</a> unless quoted (see <a href="index.html#expand-variable">Variable expansion</a>):
2015-09-17 20:17:52 +08:00
2015-09-15 23:04:49 +08:00
\fish{cli-dark}
2017-11-30 21:08:10 +08:00
>_ set a 1 2 3
>_ set 1 a b c
2015-09-15 23:04:49 +08:00
>_ echo $a$1
2016-07-16 18:27:02 +08:00
<outp>1a 2a 3a 1b 2b 3b 1c 2c 3c</outp>
2015-09-17 20:17:52 +08:00
>_ echo $a" banana"
2016-07-16 18:27:02 +08:00
<outp>1 banana 2 banana 3 banana</outp>
2015-09-17 20:17:52 +08:00
>_ echo "$a banana"
2016-07-16 18:27:02 +08:00
<outp>1 2 3 banana</outp>
2015-09-15 23:04:49 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2015-09-17 20:17:52 +08:00
This is similar to <a href="index.html#expand-brace">Brace expansion</a>.
2014-08-01 10:37:32 +08:00
\section tut_command_substitutions Command Substitutions
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Command substitutions use the output of one command as an argument to another. Unlike other shells, `fish` does not use backticks ` for command substitutions. Instead, it uses parentheses:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo In (pwd), running (uname)
2016-07-16 18:27:02 +08:00
<outp>In /home/tutorial, running FreeBSD</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
A common idiom is to capture the output of a command in a variable:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ set os (uname)
>_ echo $os
2016-07-16 18:27:02 +08:00
<outp>Linux</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
Command substitutions are not expanded within quotes. Instead, you can temporarily close the quotes, add the command substitution, and reopen them, all in the same argument:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ touch <i class="quote">"testing_"</i>(date +%s)<i class="quote">".txt"</i>
>_ ls *.txt
2016-07-16 18:27:02 +08:00
<outp>testing_1360099791.txt</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2017-06-07 04:05:23 +08:00
Unlike other shells, fish does not split command substitutions on any whitespace (like spaces or tabs), only newlines. This can be an issue with commands like `pkg-config` that print what is meant to be multiple arguments on a single line. To split it on spaces too, use `string split`.
\fish{cli-dark}
>_ printf '%s\n' (pkg-config --libs gio-2.0)
<outp>-lgio-2.0 -lgobject-2.0 -lglib-2.0</outp>
>_ printf '%s\n' (pkg-config --libs gio-2.0 | string split " ")
<outp>-lgio-2.0
-lgobject-2.0
-lglib-2.0</outp>
\endfish
2014-08-08 10:44:37 +08:00
2017-06-11 19:45:52 +08:00
\section tut_semicolon Separating Commands (Semicolon)
Like other shells, fish allows multiple commands either on separate lines or the same line.
To write them on the same line, use the semicolon (";"). That means the following two examples are equivalent:
\fish
echo fish; echo chips
# or
echo fish
echo chips
\endfish
2014-08-08 10:44:37 +08:00
\section tut_combiners Combiners (And, Or, Not)
2013-10-05 15:37:44 +08:00
2018-03-05 12:17:28 +08:00
fish supports the familiar `&&` and `||` to combine commands, and `!` to negate them:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2018-03-05 12:17:28 +08:00
>_ ./configure && make && sudo make install
\endfish
fish also supports `and`, `or`, and `not`. The first two are job modifiers and have lower precedence. Example usage:
\fish{cli-dark}
>_ cp file1.txt file1_bak.txt && cp file2.txt file2_bak.txt ; and echo "Backup successful"; or echo "Backup failed"
2016-07-16 18:27:02 +08:00
<outp>Backup failed</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2017-06-11 19:45:52 +08:00
As mentioned in <a href="#tut_semicolon">the section on the semicolon</a>, this can also be written in multiple lines, like so:
\fish
2018-03-05 12:17:28 +08:00
cp file1.txt file1_bak.txt && cp file2.txt file2_bak.txt
2017-06-11 19:45:52 +08:00
and echo "Backup successful"
or echo "Backup failed"
\endfish
2014-08-08 10:44:37 +08:00
\section tut_conditionals Conditionals (If, Else, Switch)
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Use `if`, `else if`, and `else` to conditionally execute code, based on the exit status of a command.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
if grep fish /etc/shells
echo Found fish
else if grep bash /etc/shells
echo Found bash
else
echo Got nothing
end
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2018-02-07 08:12:30 +08:00
To compare strings or numbers or check file properties (whether a file exists or is writeable and such), use <a href="commands.html#test">test</a>, like
2018-02-07 08:01:18 +08:00
\fish{cli-dark}
if test "$fish" = "flounder"
echo FLOUNDER
end
# or
if test "$number" -gt 5
echo $number is greater than five
else
echo $number is five or less
end
\endfish
2017-06-11 19:46:13 +08:00
<a href="#tut_combiners">Combiners</a> can also be used to make more complex conditions, like
\fish
if grep fish /etc/shells; and command -sq fish
echo fish is installed and configured
end
\endfish
For even more complex conditions, use `begin` and `end` to group parts of them.
2014-08-01 10:37:32 +08:00
There is also a `switch` command:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
switch (uname)
case Linux
echo Hi Tux!
case Darwin
echo Hi Hexley!
case FreeBSD NetBSD DragonFly
echo Hi Beastie!
case '*'
echo Hi, stranger!
end
2014-08-01 10:37:32 +08:00
\endfish
Note that `case` does not fall through, and can accept multiple arguments or (quoted) wildcards.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_functions Functions
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
A `fish` function is a list of commands, which may optionally take arguments. Unlike other shells, arguments are not passed in "numbered variables" like `$1`, but instead in a single list `$argv`. To create a function, use the `function` builtin:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ function say_hello
echo Hello $argv
end
>_ say_hello
2016-07-16 18:27:02 +08:00
<outp>Hello</outp>
2014-08-08 10:44:37 +08:00
>_ say_hello everybody!
2016-07-16 18:27:02 +08:00
<outp>Hello everybody!</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Unlike other shells, `fish` does not have aliases or special prompt syntax. Functions take their place.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
You can list the names of all functions with the `functions` keyword (note the plural!). `fish` starts out with a number of functions:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ functions
2016-07-16 18:27:02 +08:00
<outp>alias, cd, delete-or-exit, dirh, dirs, down-or-search, eval, export, fish_command_not_found_setup, fish_config, fish_default_key_bindings, fish_prompt, fish_right_prompt, fish_sigtrap_handler, fish_update_completions, funced, funcsave, grep, help, history, isatty, ls, man, math, nextd, nextd-or-forward-word, open, popd, prevd, prevd-or-backward-word, prompt_pwd, psub, pushd, seq, setenv, trap, type, umask, up-or-search, vared</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
You can see the source for any function by passing its name to `functions`:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ functions ls
2013-10-05 15:37:44 +08:00
function ls --description 'List contents of directory'
2014-08-01 10:37:32 +08:00
command ls -G $argv
2013-10-05 15:37:44 +08:00
end
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_loops Loops
2013-10-05 15:37:44 +08:00
While loops:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ while true
echo <i class="quote">"Loop forever"</i>
end
2016-07-16 18:27:02 +08:00
<outp>Loop forever</outp>
<outp>Loop forever</outp>
<outp>Loop forever</outp>
<outp>...</outp>
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
For loops can be used to iterate over a list. For example, a list of files:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ for file in *.txt
cp $file $file.bak
end
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
Iterating over a list of numbers can be done with `seq`:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ for x in (seq 5)
touch file_$x.txt
end
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\section tut_prompt Prompt
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
Unlike other shells, there is no prompt variable like PS1. To display your prompt, `fish` executes a function with the name `fish_prompt`, and its output is used as the prompt.
2013-10-05 15:37:44 +08:00
You can define your own prompt:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ function fish_prompt
echo "New Prompt % "
end
2016-07-16 18:27:02 +08:00
<asis>New Prompt % </asis>___
2014-08-01 10:37:32 +08:00
\endfish
Multiple lines are OK. Colors can be set via `set_color`, passing it named ANSI colors, or hex RGB values:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ function fish_prompt
set_color purple
date "+%m/%d/%y"
set_color FF0
echo (pwd) '>'
set_color normal
end
2013-10-05 15:37:44 +08:00
<span style="color: purple">02/06/13</span>
2014-08-27 02:19:24 +08:00
<span style="color: #FF0">/home/tutorial ></span>___
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
You can choose among some sample prompts by running `fish_config prompt`. `fish` also supports RPROMPT through `fish_right_prompt`.
2013-10-05 15:37:44 +08:00
2015-07-04 03:35:53 +08:00
\section tut_path $PATH
2013-10-05 15:37:44 +08:00
2015-07-04 03:35:53 +08:00
`$PATH` is an environment variable containing the directories in which `fish` searches for commands. Unlike other shells, $PATH is a [list](#tut_lists), not a colon-delimited string.
2013-10-05 15:37:44 +08:00
2016-02-29 07:12:26 +08:00
To prepend /usr/local/bin and /usr/sbin to `$PATH`, you can write:
2015-07-04 03:46:40 +08:00
\fish{cli-dark}
2016-02-29 07:12:26 +08:00
>_ set PATH /usr/local/bin /usr/sbin $PATH
2015-07-04 03:46:40 +08:00
\endfish
2017-07-15 19:32:00 +08:00
To remove /usr/local/bin from `$PATH`, you can write:
\fish{cli-dark}
>_ set PATH (string match -v /usr/local/bin $PATH)
2017-12-30 04:44:09 +08:00
\endfish
2017-07-15 19:32:00 +08:00
2015-12-24 18:19:23 +08:00
You can do so directly in `config.fish`, like you might do in other shells with `.profile`. See [this example](#path_example).
2015-07-04 03:35:53 +08:00
A faster way is to modify the `$fish_user_paths` [universal variable](#tut_universal), which is automatically prepended to `$PATH`. For example, to permanently add `/usr/local/bin` to your `$PATH`, you could write:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2015-07-04 03:46:40 +08:00
>_ set -U fish_user_paths /usr/local/bin $fish_user_paths
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2015-12-24 18:19:23 +08:00
The advantage is that you don't have to go mucking around in files: just run this once at the command line, and it will affect the current session and all future instances too. (Note: you should NOT add this line to `config.fish`. If you do, the variable will get longer each time you run fish!)
2014-08-08 10:44:37 +08:00
\section tut_startup Startup (Where's .bashrc?)
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
`fish` starts by executing commands in `~/.config/fish/config.fish`. You can create it if it does not exist.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
It is possible to directly create functions and variables in `config.fish` file, using the commands shown above. For example:
2013-10-05 15:37:44 +08:00
2015-07-04 03:35:53 +08:00
<a name="path_example"></a>
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ cat ~/.config/fish/config.fish
2013-10-05 15:37:44 +08:00
set -x PATH $PATH /sbin/
function ll
ls -lh $argv
end
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
However, it is more common and efficient to use autoloading functions and universal variables.
2013-10-05 15:37:44 +08:00
2015-07-04 03:35:53 +08:00
\section tut_autoload Autoloading Functions
2013-10-05 15:37:44 +08:00
2014-08-08 10:44:37 +08:00
When `fish` encounters a command, it attempts to autoload a function for that command, by looking for a file with the name of that command in `~/.config/fish/functions/`.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
For example, if you wanted to have a function `ll`, you would add a text file `ll.fish` to `~/.config/fish/functions`:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ cat ~/.config/fish/functions/ll.fish
2013-10-05 15:37:44 +08:00
function ll
2014-08-01 10:37:32 +08:00
ls -lh $argv
2013-10-05 15:37:44 +08:00
end
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
This is the preferred way to define your prompt as well:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ cat ~/.config/fish/functions/fish_prompt.fish
2013-10-05 15:37:44 +08:00
function fish_prompt
2014-08-08 10:44:37 +08:00
echo (pwd) "> "
2013-10-05 15:37:44 +08:00
end
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
See the documentation for <a href="commands.html#funced">funced</a> and <a href="commands.html#funcsave">funcsave</a> for ways to create these files automatically.
2013-10-05 15:37:44 +08:00
2015-07-04 03:35:53 +08:00
\section tut_universal Universal Variables
2013-10-05 15:37:44 +08:00
2015-04-26 00:53:15 +08:00
A universal variable is a variable whose value is shared across all instances of `fish`, now and in the future – even after a reboot. You can make a variable universal with `set -U`:
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ set -U EDITOR vim
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
Now in another shell:
2014-08-01 10:37:32 +08:00
\fish{cli-dark}
2014-08-08 10:44:37 +08:00
>_ echo $EDITOR
2013-10-05 15:37:44 +08:00
vim
2014-08-01 10:37:32 +08:00
\endfish
2013-10-05 15:37:44 +08:00
2018-06-04 16:10:01 +08:00
\section tut_switching_to_fish Switching to fish?
If you wish to use fish (or any other shell) as your default shell,
you need to enter your new shell's executable `/usr/local/bin/fish` in two places:
- add `/usr/local/bin/fish` to `/etc/shells`
2019-01-18 07:35:05 +08:00
- change your default shell with `chsh -s /usr/local/bin/fish`
2018-06-04 16:10:01 +08:00
You can use the following commands for this:
Add the fish shell `/usr/local/bin/fish`
to `/etc/shells` with:
\fish{cli-dark}
>echo /usr/local/bin/fish | sudo tee -a /etc/shells
\endfish
Change your default shell to fish with:
\fish{cli-dark}
>chsh -s /usr/local/bin/fish
\endfish
(To change it back to another shell, just substitute `/usr/local/bin/fish`
with `/bin/bash`, `/bin/tcsh` or `/bin/zsh` as appropriate in the steps above.)
2015-07-04 03:35:53 +08:00
\section tut_more Ready for more?
2013-10-05 15:37:44 +08:00
2014-08-27 07:30:08 +08:00
If you want to learn more about fish, there is <a href="index.html">lots of detailed documentation</a>, an <a href="https://lists.sourceforge.net/lists/listinfo/fish-users">official mailing list</a>, the IRC channel \#fish on `irc.oftc.net`, and the <a href="https://github.com/fish-shell/fish-shell/">github page</a>.
2013-10-05 15:37:44 +08:00
2014-08-01 10:37:32 +08:00
\htmlonly[block]
2013-10-05 15:37:44 +08:00
</div>
2014-08-01 10:37:32 +08:00
\endhtmlonly
*/