fish (Unix shell)

From Wikipedia, the free encyclopedia
(Redirected from Fish shell)
Jump to navigation Jump to search

fish
Original authorAxel Liljencrantz
DeveloperFish-shell developers[1]
Initial release13 February 2005; 21 years ago (2005-02-13)
Repository
  • {{URL|example.com|optional display text}}Lua error in Module:EditAtWikidata at line 29: attempt to index field 'wikibase' (a nil value).
Written inRust since v4.0,[2] C++ up to v3.7.1[3]
Engine
    Lua error in Module:EditAtWikidata at line 29: attempt to index field 'wikibase' (a nil value).
    Operating systemUnix-like
    TypeUnix shell
    LicenseGPL-2.0-only[4]
    Websitefishshell.com

    fish (friendly interactive shell; stylized in lowercase) is a Unix-like shell with a focus on interactivity and usability. fish is designed to be feature-rich by default, rather than highly configurable,[5] and does not adhere to POSIX shell standards by design.[6]

    Features

    [edit | edit source]

    fish displays incremental suggestions as the user types, based on command history and the current directory. This functions similarly to Bash's Ctrl+R history search, but is always on, giving the user continuous feedback while typing commands. fish also includes feature-rich tab completion, with support for expanding file paths (with wildcards and brace expansion), environment variables, and command-specific completions. Command-specific completions, including options with descriptions, can be to some extent generated from the commands' man pages, but custom completions can also be included with software or written by users of the shell.[7]

    The creator of fish preferred to add new features as commands rather than syntax. This made features more discoverable, as the built-in features allow searching commands with options and help texts. Functions can also include human readable descriptions. A special help command gives access to all the fish documentation in the user's web browser.[8]

    Syntax

    [edit | edit source]

    The syntax resembles a POSIX compatible shell (such as Bash), but deviates in many ways[9]

    # Variable assignment
    #
    # Set the variable 'foo' to the value 'bar'.
    # fish doesn't use the = operator, which is inherently whitespace sensitive.
    # The 'set' command extends to work with arrays, scoping, etc.
    
    > set foo bar
    > echo $foo
    bar
    
    # Command substitution
    #
    # Assign the output of the command 'pwd' into the variable 'wd'.
    # fish doesn't use backticks (``), which can't be nested and may be confused with single quotes (' ').
    
    > set wd (pwd)
    > set wd $(pwd) # since version 3.4
    > echo $wd
    ~
    
    # Array variables. 'A' becomes an array with 5 values:
    > set A 3 5 7 9 12
    # Array slicing. 'B' becomes the first two elements of 'A':
    > set B $A[1 2]
    > echo $B
    3 5
    # You can index with other arrays and even command
    # substitution output:
    > echo $A[(seq 3)]
    3 5 7
    # Erase the third and fifth elements of 'A'
    > set --erase A[$B]
    > echo $A
    3 5 9
    
    # for-loop, convert jpegs to pngs
    > for i in *.jpg
          convert $i (basename $i .jpg).png
      end
    
    # fish supports multi-line history and editing.
    # Semicolons work like newlines:
    > for i in *.jpg; convert $i (basename $i .jpg).png; end
    
    # while-loop, read lines /etc/passwd and output the fifth
    # colon-separated field from the file. This should be
    # the user description.
    > while read line
          set arr (echo $line|tr : \n)
          echo $arr[5]
      end < /etc/passwd
    
    # String replacement (replacing all i by I)
    > string replace -a "i" "I" "Wikipedia"
    WIkIpedIa
    

    No implicit subshell

    [edit | edit source]

    Some language constructs, like pipelines, functions and loops, have been implemented using so called subshells in other shell languages. Subshells are child programs that run a few commands to perform a task, then exit back to the parent shell. This implementation detail typically has the side effect that any state changes made in the subshell, such as variable assignments, do not propagate to the main shell. fish never creates subshells for language features; all builtins happen within the parent shell.

    # This will not work in many other shells, since the 'read' builtin
    # will run in its own subshell. In Bash, the right side of the pipe
    # can't have any side effects. In ksh, the below command works, but
    # the left side can't have any side effects. In fish and zsh, both
    # sides can have side effects.
    > cat *.txt | read line
    

    Variable assignment example

    [edit | edit source]

    This Bash example doesn't do what it seems: because the loop body is a subshell, the update to $found is not persistent.

    found=''
    cat /etc/fstab | while read dev mnt rest; do
      if test "$mnt" = "/"; then
        found="$dev"
      fi
    done
    

    Workaround:

    found=''
    while read dev mnt rest; do
      if test "$mnt" = "/"; then
        found="$dev"
      fi
    done < /etc/fstab
    

    Fish example:

    set found ''
    cat /etc/fstab | while read dev mnt rest
      if test "$mnt" = "/"
        set found $dev
      end
    end
    

    Universal variables

    [edit | edit source]

    fish has a feature known as universal variables, which allows a user to permanently assign a value to a variable across all the user's running fish shells. The variable value is remembered across logouts and reboots, and updates are immediately propagated to all running shells.

    # This will make emacs the default text editor. The '--universal' (or '-U') tells fish to
    # make this a universal variable.
    > set --universal EDITOR emacs
    
    # This command will make the current working directory part of the fish
    # prompt turn blue on all running fish instances.
    > set --universal fish_color_cwd blue
    

    Other features

    [edit | edit source]

    Bash/fish translation table

    [edit | edit source]
    Feature Bash syntax fish syntax Comment
    variable expansion:
    with word splitting and glob interpretation
    $var
    

    or

    ${var[@]}
    

    or

    ${var[*]}
    
    deliberately omitted Identified as a primary cause of bugs in posix compatible shell languages[11]
    variable expansion:
    scalar
    "$var"
    
    deliberately omitted Every variable is an array
    variable expansion:
    array
    "${var[@]}"
    
    $var
    
    Quoting not necessary to suppress word splitting and glob interpretation. Instead, quoting signifies serialization.
    variable expansion:
    as a space separated string
    "${var[*]}"
    
    "$var"
    
    edit line in text editor Ctrl+X,Ctrl+E Alt+E Upon invocation, moves line input to a text editor
    evaluate line input Ctrl+Alt+E [12] Evaluates expressions in-place on the line editor
    history completion Ctrl+R implicit
    history substitution !! deliberately omitted Not discoverable
    explicit subshell
    (expression)
    
    fish -c expression
    
    command substitution
    "$(expression)"
    

    "$(expression)" or (expression | string collect)

    process substitution
    <(expression)
    
    (expression | psub)
    
    Command, not syntax
    logical operators
    !cmd && echo FAIL || echo OK
    
    not command
    and echo FAIL
    or echo OK
    
    variable assignment
    var=value
    
    set var value
    
    string processing:
    replace
    "${HOME/alice/bob}"
    
    string replace alice bob $HOME
    
    string processing:
    remove prefix or suffix pattern, non-greedily or greedily
    var=a.b.c
    "${var#*.}"  #b.c
    "${var##*.}" #c
    "${var%.*}"  #a.b
    "${var%%.*}" #a
    
    string replace --regex '.*?\.(.*)' '$1' a.b.c #b.c
    string replace --regex '.*\.(.*)' '$1' a.b.c  #c
    string replace --regex '(.*)\..*' '$1' a.b.c  #a.b
    string replace --regex '(.*?)\..*' '$1' a.b.c #a
    
    export variable
    export var
    
    set --export var
    
    Options discoverable via tab completion
    function-local variable
    local var
    
    by default
    scope-local variable no equivalent
    set --local var
    
    remove variable
    unset var
    
    set --erase var
    
    check if a variable exists
    test -v var
    
    set --query var
    
    array initialization
    var=( a b c )
    
    set var a b c
    
    Every variable is an array
    array iteration
    for i in "${var[@]}"; do
      echo "$i"
    done
    
    for i in $var
      echo $i
    end
    
    argument vector:
    all arguments
    "$@"
    
    $argv
    
    argument vector:
    indexing
    "$1"
    
    $argv[1]
    
    argument vector:
    length
    $#
    
    (count $argv)
    
    argument vector:
    shift
    shift
    
    set --erase argv[1]
    
    array representation in environment variables
    PATH="$PATH:$HOME/.local/bin"
    
    set PATH $PATH $HOME/.local/bin
    
    fish assumes colon as array delimiter for translating variables to and from the environment. This aligns with many array-like environment variables, like $PATH and $LS_COLORS.
    export and run
    LANG=C.UTF-8 python3
    
    env LANG=C.UTF-8 python3
    
    env LANG=C.UTF-8 python3 works in any shell, as env is a standalone program.
    arithmetic
    $((10/3))
    
    math '10/3'
    
    expr 10 / 3 works in any shell, as expr is a standalone program.
    escape sequence
    $'\e'
    
    \e
    
    printf '\e' works in both shells; their printf builtins are both compatible with the GNU printf standalone program.[13]
    single quoted string:
    escape sequences
    'mom'\''s final backslash: \'
    
    'mom\'s final backslash: \\'
    
    Bash only requires replacement of the single quote itself in single quoted strings, but the replacement is 4 characters long. The same replacement works in fish, but fish supports a regular escape sequence for this, thus requires escaping backslashes too (except permits single backslashes that don't precede another backslash or single quote).

    See also

    [edit | edit source]

    Lua error in mw.title.lua at line 392: bad argument #2 to 'title.new' (unrecognized namespace name 'Portal').

    References

    [edit | edit source]
    1. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    2. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    3. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    4. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    5. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    6. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    7. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    8. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    9. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    10. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    11. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    12. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    13. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
    [edit | edit source]
    • Lua error in Module:Official_website at line 94: attempt to index field 'wikibase' (a nil value). – containing documentation and downloads
    • fish-shell on GitHub (active)
    • Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value). (obsolete)
    • fish / fish on SourceForge (obsolete)
    • fish-users – general discussion list for fish users
    • Shell Translation Dictionary – another Bash/fish translation table