Since fish 3.1 you can set an environment variable for just one command using the ``key=value some command`` syntax, like in other shells. The two lines below behave identically - unlike other shells, fish will output ``value`` both times::
Note that "exported" is not a :ref:`scope <variables-scope>`, but an additional bit of state. A variable can be global and exported or local and exported or even universal and exported. Typically it makes sense to make an exported variable global.
Use ``set -q var``. For example, ``if set -q var; echo variable defined; end``. To check multiple variables you can combine with ``and`` and ``or`` like so::
Keep in mind that a defined variable could also be empty, either by having no elements (if set like ``set var``) or only empty elements (if set like ``set var ""``). Read on for how to deal with those.
Use ``string length -q -- $var``. For example, ``if string length -q -- $var; echo not empty; end``. Note that ``string length`` will interpret a list of multiple variables as a disjunction (meaning any/or)::
if string length -q -- $var1 $var2 $var3
echo at least one of these variables is not empty
end
Alternatively, use ``test -n "$var"``, but remember that **the variable must be double-quoted**. For example, ``if test -n "$var"; echo not empty; end``. The ``test`` command provides its own and (-a) and or (-o)::
if test -n "$var1" -o -n "$var2" -o -n "$var3"
echo at least one of these variables is not empty
end
If you want to know if a variable has *no elements*, use ``set -q var[1]``.
Why doesn't ``set -Ux`` (exported universal variables) seem to work?
Use the web configuration tool, :doc:`fish_config <cmds/fish_config>`, or alter the :ref:`fish_color family of environment variables <variables-color>`.
Change the value of the variable ``fish_greeting`` or create a :doc:`fish_greeting <cmds/fish_greeting>` function. For example, to remove the greeting use::
Type some part of the command, and then hit the :kbd:`up` (``↑``) or :kbd:`down` (``↓``) arrow keys to navigate through history matches, or press :kbd:`ctrl-r` to open the history in a searchable pager. In this pager you can press :kbd:`ctrl-r` or :kbd:`ctrl-s` to move to older or younger history respectively.
Additional default key bindings include :kbd:`ctrl-p` (up) and :kbd:`ctrl-n` (down). See :ref:`Searchable command history <history-search>` for more information.
Because history substitution is an awkward interface that was invented before interactive line editing was even possible. Instead of adding this pseudo-syntax, fish opts for nice history searching and recall features. Switching requires a small change of habits: if you want to modify an old line/word, first recall it, then edit.
As a special case, most of the time history substitution is used as ``sudo !!``. In that case just press :kbd:`alt-s`, and it will recall your last commandline with ``sudo`` prefixed (or toggle a ``sudo`` prefix on the current commandline if there is anything).
- Like other shells, the Up arrow, ``up`` recalls whole lines, starting from the last executed line. So instead of typing ``!!``, you would just hit the up-arrow.
- If the line you want is far back in the history, type any part of the line and then press Up one or more times. This will filter the recalled lines to ones that include this text, and you will get to the line you want much faster. This replaces "!vi", "!?bar.c" and the like. If you want to see more context, you can press ``ctrl-r`` to open the history in the pager.
abbr -a !! --position anywhere --function last_history_item
Run this and ``!!`` will be replaced with the last history entry, anywhere on the commandline. Put it into :ref:`config.fish <configuration>` to keep it.
It also supports the familiar ``$()`` syntax, even in quotes. Backticks are not supported because they are discouraged even in POSIX shells. They nest poorly and are hard to tell from single quotes (``''``).
In the overwhelming majority of cases, splitting on spaces is unwanted, so this is an improvement. This is why you hear about problems with filenames with spaces, after all.
appear to work, because most of the time the string doesn't match and so it passes along the ``string-*``, which is then interpreted by the receiving program.
But it also means that these commands can stop working at any moment once a matching file is encountered (because it has been created or the command is executed in a different working directory), and to deal with that bash needs workarounds like
whether it's in an interactive or login or non-interactive or non-login shell.
This simplifies matters, but it also means when config.fish generates output, it will do that even in non-interactive shells like the one ssh/scp/rsync start when they connect.
Anything in config.fish that produces output should be guarded with ``status is-interactive`` (or ``status is-login`` if you prefer)::
The same applies for example when you start ``tmux`` in config.fish without guards, which will cause a message like ``sessions should be nested with care, unset $TMUX to force``.
In a terminal, the application running inside it and the terminal itself need to agree on the width of characters in order to handle cursor movement.
This is more important to fish than other shells because features like syntax highlighting and autosuggestions are implemented by moving the cursor.
Sometimes, there is disagreement on the width. There are numerous causes and fixes for this:
- It is possible the character is simply too new for your system to know - in this case you need to refrain from using it.
- Fish or your terminal might not know about the character or handle it wrong - in this case fish or your terminal needs to be fixed, or you need to update to a fixed version.
- The character has an "ambiguous" width and fish thinks that means a width of X while your terminal thinks it's Y. In this case you either need to change your terminal's configuration or set $fish_ambiguous_width to the correct value.
- The character is an emoji and the host system only supports Unicode 8, while you are running the terminal on a system that uses Unicode >= 9. In this case set $fish_emoji_width to 2.
This also means that a few things are unsupportable:
- Non-monospace fonts - there is *no way* for fish to figure out what width a specific character has as it has no influence on the terminal's font rendering.
- Different widths for multiple ambiguous width characters - there is no way for fish to know which width you assign to each character.
If you installed it with a package manager, just use that package manager's uninstall function. If you built fish yourself, assuming you installed it to /usr/local, do this::