mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-25 01:16:36 +08:00
591 lines
18 KiB
Plaintext
591 lines
18 KiB
Plaintext
/**
|
||
\page tutorial Tutorial
|
||
\htmlonly[block]
|
||
<div class="fish_left_bar">
|
||
<div class="logo"></div>
|
||
<div class="menu tutorial_menu">
|
||
\endhtmlonly
|
||
- <a href="#tut_why_fish">Why fish?</a>
|
||
- <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>
|
||
- <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>
|
||
- <a href="#tut_path">$PATH</a>
|
||
- <a href="#tut_startup">Startup</a>
|
||
- <a href="#tut_autoload">Autoloading Functions</a>
|
||
- <a href="#tut-more">Ready for more?</a>
|
||
|
||
\htmlonly[block]
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tutorial fish_right_bar">
|
||
<h1 class="interior_title">fish tutorial</h1>
|
||
\endhtmlonly
|
||
|
||
\section tut_why_fish Why fish?
|
||
|
||
`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.
|
||
|
||
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!
|
||
|
||
|
||
\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.
|
||
|
||
When you start `fish`, you should see this:
|
||
|
||
\fish{cli-dark}
|
||
<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> ~>____
|
||
\endfish
|
||
|
||
`fish` comes with a default prompt that shows your username, hostname, and working directory. You'll see <a href="#tut_prompt">how to change your prompt</a> further down. From now on, we'll pretend your prompt is just a '`>`' to save space.
|
||
|
||
|
||
\section tut_running_commands Running Commands
|
||
|
||
`fish` runs commands like other shells: you type a command, followed by its arguments. Spaces are separators:
|
||
|
||
\fish{cli-dark}
|
||
>_ echo hello world
|
||
<outp>hello world</outp>
|
||
\endfish
|
||
|
||
You can include a literal space in an argument with a backslash, or by using single or double quotes:
|
||
|
||
\fish{cli-dark}
|
||
>_ mkdir My\ Files
|
||
>_ cp ~/Some\ File 'My Files'
|
||
>_ ls "My Files"
|
||
<outp>Some File</outp>
|
||
\endfish
|
||
|
||
Commands can be chained with semicolons.
|
||
|
||
|
||
\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.
|
||
|
||
\fish{cli-dark}
|
||
>_ man set
|
||
<outp>set - handle shell variables</outp>
|
||
<outp> Synopsis...</outp>
|
||
\endfish
|
||
|
||
|
||
\section tut_syntax_highlighting Syntax Highlighting
|
||
|
||
You'll quickly notice that `fish` performs syntax highlighting as you type. Invalid commands are colored red by default:
|
||
|
||
\fish{cli-dark}
|
||
>_ <error>/bin/mkd</error>
|
||
\endfish
|
||
|
||
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:
|
||
|
||
\fish{cli-dark}
|
||
>_ /bin/mkdir
|
||
\endfish
|
||
|
||
`fish` will underline valid file paths as you type them:
|
||
|
||
\fish{cli-dark}
|
||
>_ cat <u>~/somefi</u>___
|
||
\endfish
|
||
|
||
This tells you that there exists a file that starts with '`somefi`', which is useful feedback as you type.
|
||
|
||
These colors, and many more, can be changed by running `fish_config`, or by modifying variables directly.
|
||
|
||
|
||
\section tut_wildcards Wildcards
|
||
|
||
`fish` supports the familiar wildcard `*`. To list all JPEG files:
|
||
|
||
\fish{cli-dark}
|
||
>_ ls *.jpg
|
||
<outp>lena.jpg</outp>
|
||
<outp>meena.jpg</outp>
|
||
<outp>santa maria.jpg</outp>
|
||
\endfish
|
||
|
||
You can include multiple wildcards:
|
||
|
||
\fish{cli-dark}
|
||
>_ ls l*.p*
|
||
<outp>lena.png</outp>
|
||
<outp>lesson.pdf</outp>
|
||
\endfish
|
||
|
||
Especially powerful is the recursive wildcard ** which searches directories recursively:
|
||
|
||
\fish{cli-dark}
|
||
>_ ls /var/**.log
|
||
<outp>/var/log/system.log</outp>
|
||
<outp>/var/run/sntp.log</outp>
|
||
\endfish
|
||
|
||
If that directory traversal is taking a long time, you can @key{Control,C} out of it.
|
||
|
||
|
||
\section tut_pipes_and_redirections Pipes and Redirections
|
||
|
||
You can pipe between commands with the usual vertical bar:
|
||
|
||
\fish{cli-dark}
|
||
>_ echo hello world | wc
|
||
<outp> 1 2 12</outp>
|
||
\endfish
|
||
|
||
stdin and stdout can be redirected via the familiar < and >. Unlike other shells, stderr is redirected with a caret ^
|
||
|
||
\fish{cli-dark}
|
||
>_ grep fish < /etc/shells > ~/output.txt ^ ~/errors.txt
|
||
\endfish
|
||
|
||
|
||
\section tut_autosuggestions Autosuggestions
|
||
|
||
`fish` suggests commands as you type, and shows the suggestion to the right of the cursor, in gray. For example:
|
||
|
||
\fish{cli-dark}
|
||
>_ <error>/bin/h</error><s>___ostname</s>
|
||
\endfish
|
||
|
||
It knows about paths and options:
|
||
|
||
\fish{cli-dark}
|
||
>_ grep --i<s>___gnore-case</s>
|
||
\endfish
|
||
|
||
And history too. Type a command once, and you can re-summon it by just typing a few letters:
|
||
|
||
\fish{cli-dark}
|
||
>_ <error>r</error><s>___sync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo</s>
|
||
\endfish
|
||
|
||
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.
|
||
|
||
\section tut_tab_completions Tab Completions
|
||
|
||
`fish` comes with a rich set of tab completions, that work "out of the box."
|
||
|
||
Press @key{Tab}, and `fish` will attempt to complete the command, argument, or path:
|
||
|
||
\fish{cli-dark}
|
||
>_ <error>/pri</error> @key{Tab} → /private/
|
||
\endfish
|
||
|
||
If there's more than one possibility, it will list them:
|
||
|
||
\fish{cli-dark}
|
||
>_ <error>~/stuff/s</error> @key{Tab}
|
||
<outp><m>~/stuff/s</m>cript.sh <i>(Executable, 4.8kB)</i> <m>~/stuff/s</m>ources/ <i>(Directory)</i></outp>
|
||
\endfish
|
||
|
||
Hit tab again to cycle through the possibilities.
|
||
|
||
`fish` can also complete many commands, like git branches:
|
||
|
||
\fish{cli-dark}
|
||
>_ git merge pr @key{Tab} → git merge prompt_designer
|
||
>_ git checkout b @key{Tab}
|
||
<outp><m>b</m>uiltin_list_io_merge <i>(Branch)</i> <m>b</m>uiltin_set_color <i>(Branch)</i> <m>b</m>usted_events <i>(Tag)</i></outp>
|
||
\endfish
|
||
|
||
Try hitting tab and see what `fish` can do!
|
||
|
||
\section tut_variables Variables
|
||
|
||
Like other shells, a dollar sign performs variable substitution:
|
||
|
||
\fish{cli-dark}
|
||
>_ echo My home directory is $HOME
|
||
<outp>My home directory is /home/tutorial</outp>
|
||
\endfish
|
||
|
||
Variable substitution also occurs in double quotes, but not single quotes:
|
||
|
||
\fish{cli-dark}
|
||
>_ echo "My current directory is $PWD"
|
||
<outp>My current directory is /home/tutorial</outp>
|
||
>_ echo 'My current directory is $PWD'
|
||
<outp>My current directory is $PWD</outp>
|
||
\endfish
|
||
|
||
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.
|
||
|
||
\fish{cli-dark}
|
||
>_ set name 'Mister Noodle'
|
||
>_ echo $name
|
||
<outp>Mister Noodle</outp>
|
||
\endfish
|
||
|
||
(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.)
|
||
|
||
Unlike other shells, variables are not further split after substitution:
|
||
|
||
\fish{cli-dark}
|
||
>_ mkdir $name
|
||
>_ ls
|
||
<outp>Mister Noodle</outp>
|
||
\endfish
|
||
|
||
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.
|
||
|
||
|
||
\section tut_exit_status Exit Status
|
||
|
||
Unlike other shells, `fish` stores the exit status of the last command in `$status` instead of `$?`.
|
||
|
||
\fish{cli-dark}
|
||
>_ false
|
||
>_ echo $status
|
||
<outp>1</outp>
|
||
\endfish
|
||
|
||
Zero is considered success, and non-zero is failure.
|
||
|
||
|
||
\section tut_exports Exports (Shell Variables)
|
||
|
||
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`.
|
||
|
||
\fish{cli-dark}
|
||
>_ set -x MyVariable SomeValue
|
||
>_ env | grep MyVariable
|
||
<outp><sm>MyVariable</sm>=SomeValue</outp>
|
||
\endfish
|
||
|
||
You can erase a variable with `-e` or `--erase`
|
||
|
||
\fish{cli-dark}
|
||
>_ set -e MyVariable
|
||
>_ env | grep MyVariable
|
||
<outp>(no output)</outp>
|
||
\endfish
|
||
|
||
|
||
\section tut_lists Lists
|
||
|
||
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.
|
||
|
||
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.
|
||
|
||
Other variables, like `$PATH`, really do have multiple values. During variable expansion, the variable expands to become multiple arguments:
|
||
|
||
\fish{cli-dark}
|
||
>_ echo $PATH
|
||
<outp>/usr/bin /bin /usr/sbin /sbin /usr/local/bin</outp>
|
||
\endfish
|
||
|
||
Lists cannot contain other lists: there is no recursion. A variable is a list of strings, full stop.
|
||
|
||
Get the length of a list with `count`:
|
||
|
||
\fish{cli-dark}
|
||
>_ count $PATH
|
||
<outp>5</outp>
|
||
\endfish
|
||
|
||
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:
|
||
|
||
\fish{cli-dark}
|
||
>_ set PATH $PATH /usr/local/bin
|
||
\endfish
|
||
|
||
|
||
You can access individual elements with square brackets. Indexing starts at 1 from the beginning, and -1 from the end:
|
||
|
||
\fish{cli-dark}
|
||
>_ echo $PATH
|
||
<outp>/usr/bin /bin /usr/sbin /sbin /usr/local/bin</outp>
|
||
>_ echo $PATH[1]
|
||
<outp>/usr/bin</outp>
|
||
>_ echo $PATH[-1]
|
||
<outp>/usr/local/bin</outp>
|
||
\endfish
|
||
|
||
You can also access ranges of elements, known as "slices:"
|
||
|
||
\fish{cli-dark}
|
||
>_ echo $PATH[1..2]
|
||
<outp>/usr/bin /bin</outp>
|
||
>_ echo $PATH[-1..2]
|
||
<outp>/usr/local/bin /sbin /usr/sbin /bin</outp>
|
||
\endfish
|
||
|
||
You can iterate over a list (or a slice) with a for loop:
|
||
|
||
\fish{cli-dark}
|
||
>_ for val in $PATH
|
||
echo "entry: $val"
|
||
end
|
||
<outp>entry: /usr/bin/</outp>
|
||
<outp>entry: /bin</outp>
|
||
<outp>entry: /usr/sbin</outp>
|
||
<outp>entry: /sbin</outp>
|
||
<outp>entry: /usr/local/bin</outp>
|
||
\endfish
|
||
|
||
|
||
\section tut_command_substitutions Command Substitutions
|
||
|
||
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:
|
||
|
||
\fish{cli-dark}
|
||
>_ echo In (pwd), running (uname)
|
||
<outp>In /home/tutorial, running FreeBSD</outp>
|
||
\endfish
|
||
|
||
A common idiom is to capture the output of a command in a variable:
|
||
|
||
\fish{cli-dark}
|
||
>_ set os (uname)
|
||
>_ echo $os
|
||
<outp>Linux</outp>
|
||
\endfish
|
||
|
||
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:
|
||
|
||
\fish{cli-dark}
|
||
>_ touch <i class="quote">"testing_"</i>(date +%s)<i class="quote">".txt"</i>
|
||
>_ ls *.txt
|
||
<outp>testing_1360099791.txt</outp>
|
||
\endfish
|
||
|
||
|
||
\section tut_combiners Combiners (And, Or, Not)
|
||
|
||
Unlike other shells, `fish` does not have special syntax like && or || to combine commands. Instead it has commands `and`, `or`, and `not`.
|
||
|
||
\fish{cli-dark}
|
||
>_ cp file1.txt file1_bak.txt; and echo "Backup successful"; or echo "Backup failed"
|
||
<outp>Backup failed</outp>
|
||
\endfish
|
||
|
||
|
||
\section tut_conditionals Conditionals (If, Else, Switch)
|
||
|
||
Use `if`, `else if`, and `else` to conditionally execute code, based on the exit status of a command.
|
||
|
||
\fish{cli-dark}
|
||
if grep fish /etc/shells
|
||
echo Found fish
|
||
else if grep bash /etc/shells
|
||
echo Found bash
|
||
else
|
||
echo Got nothing
|
||
end
|
||
\endfish
|
||
|
||
There is also a `switch` command:
|
||
|
||
\fish{cli-dark}
|
||
switch (uname)
|
||
case Linux
|
||
echo Hi Tux!
|
||
case Darwin
|
||
echo Hi Hexley!
|
||
case FreeBSD NetBSD DragonFly
|
||
echo Hi Beastie!
|
||
case '*'
|
||
echo Hi, stranger!
|
||
end
|
||
\endfish
|
||
|
||
Note that `case` does not fall through, and can accept multiple arguments or (quoted) wildcards.
|
||
|
||
|
||
\section tut_functions Functions
|
||
|
||
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:
|
||
|
||
\fish{cli-dark}
|
||
>_ function say_hello
|
||
echo Hello $argv
|
||
end
|
||
>_ say_hello
|
||
<outp>Hello</outp>
|
||
>_ say_hello everybody!
|
||
<outp>Hello everybody!</outp>
|
||
\endfish
|
||
|
||
Unlike other shells, `fish` does not have aliases or special prompt syntax. Functions take their place.
|
||
|
||
You can list the names of all functions with the `functions` keyword (note the plural!). `fish` starts out with a number of functions:
|
||
|
||
\fish{cli-dark}
|
||
>_ functions
|
||
<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, sgrep, trap, type, umask, up-or-search, vared</outp>
|
||
\endfish
|
||
|
||
You can see the source for any function by passing its name to `functions`:
|
||
|
||
\fish{cli-dark}
|
||
>_ functions ls
|
||
function ls --description 'List contents of directory'
|
||
command ls -G $argv
|
||
end
|
||
\endfish
|
||
|
||
|
||
\section tut_loops Loops
|
||
|
||
While loops:
|
||
|
||
\fish{cli-dark}
|
||
>_ while true
|
||
echo <i class="quote">"Loop forever"</i>
|
||
end
|
||
<outp>Loop forever</outp>
|
||
<outp>Loop forever</outp>
|
||
<outp>Loop forever</outp>
|
||
<outp>...</outp>
|
||
\endfish
|
||
|
||
For loops can be used to iterate over a list. For example, a list of files:
|
||
|
||
\fish{cli-dark}
|
||
>_ for file in *.txt
|
||
cp $file $file.bak
|
||
end
|
||
\endfish
|
||
|
||
Iterating over a list of numbers can be done with `seq`:
|
||
|
||
\fish{cli-dark}
|
||
>_ for x in (seq 5)
|
||
touch file_$x.txt
|
||
end
|
||
\endfish
|
||
|
||
|
||
\section tut_prompt Prompt
|
||
|
||
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.
|
||
|
||
You can define your own prompt:
|
||
|
||
\fish{cli-dark}
|
||
>_ function fish_prompt
|
||
echo "New Prompt % "
|
||
end
|
||
<asis>New Prompt % </asis>___
|
||
\endfish
|
||
|
||
Multiple lines are OK. Colors can be set via `set_color`, passing it named ANSI colors, or hex RGB values:
|
||
|
||
\fish{cli-dark}
|
||
>_ function fish_prompt
|
||
set_color purple
|
||
date "+%m/%d/%y"
|
||
set_color FF0
|
||
echo (pwd) '>'
|
||
set_color normal
|
||
end
|
||
<span style="color: purple">02/06/13</span>
|
||
<span style="color: #FF0">/home/tutorial ></span>___
|
||
\endfish
|
||
|
||
You can choose among some sample prompts by running `fish_config prompt`. `fish` also supports RPROMPT through `fish_right_prompt`.
|
||
|
||
\section tut-path $PATH
|
||
|
||
`$PATH` is an environment variable containing the directories in which `fish` searches for commands. Instead of separating entries with a colon, $PATH is a list. You can modify $PATH in a few ways:
|
||
|
||
-# By modifying the `$fish_user_paths` variable, which is automatically appended to `$PATH`. For example, to permanently add `/usr/local/bin` to your `$PATH`, you could write:
|
||
|
||
\fish{cli-dark}
|
||
>_ set -U fish_user_paths $fish_user_paths /usr/local/bin
|
||
\endfish
|
||
|
||
-# Directly in config.fish (see below).
|
||
|
||
|
||
\section tut_startup Startup (Where's .bashrc?)
|
||
|
||
`fish` starts by executing commands in `~/.config/fish/config.fish`. You can create it if it does not exist.
|
||
|
||
It is possible to directly create functions and variables in `config.fish` file, using the commands shown above. For example:
|
||
|
||
\fish{cli-dark}
|
||
>_ cat ~/.config/fish/config.fish
|
||
|
||
set -x PATH $PATH /sbin/
|
||
|
||
function ll
|
||
ls -lh $argv
|
||
end
|
||
\endfish
|
||
|
||
However, it is more common and efficient to use autoloading functions and universal variables.
|
||
|
||
\section tut-autoload Autoloading Functions
|
||
|
||
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/`.
|
||
|
||
For example, if you wanted to have a function `ll`, you would add a text file `ll.fish` to `~/.config/fish/functions`:
|
||
|
||
\fish{cli-dark}
|
||
>_ cat ~/.config/fish/functions/ll.fish
|
||
function ll
|
||
ls -lh $argv
|
||
end
|
||
\endfish
|
||
|
||
This is the preferred way to define your prompt as well:
|
||
|
||
\fish{cli-dark}
|
||
>_ cat ~/.config/fish/functions/fish_prompt.fish
|
||
function fish_prompt
|
||
echo (pwd) "> "
|
||
end
|
||
\endfish
|
||
|
||
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.
|
||
|
||
\section tut-universal Universal Variables
|
||
|
||
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`:
|
||
|
||
\fish{cli-dark}
|
||
>_ set -U EDITOR vim
|
||
\endfish
|
||
|
||
Now in another shell:
|
||
|
||
\fish{cli-dark}
|
||
>_ echo $EDITOR
|
||
vim
|
||
\endfish
|
||
|
||
\section tut-more Ready for more?
|
||
|
||
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>.
|
||
|
||
\htmlonly[block]
|
||
</div>
|
||
\endhtmlonly
|
||
*/
|