$0 Argument Zero

The path-name of the shell or shell script. When running ~/foo/bar/baz.sh, from the current working directory ~/foo, parent and name can be computed using the snippet below.

    echo "# path    ${0}     "
    # path    ./bar/baz.sh

    echo "# parent  ${0%/*}  "
    # parent  ./bar

    echo "# name    ${0##*/} "
    # name    baz.sh
  

$1, $2, etc. Positional Arguments

Positional parameter at position 1, 2 etc. The provided snippet parses key1 foo key2 bar ... into variables pair-wise, meaning echo "$key1" will show foo etc.

    while [[ $# -gt 0 ]]; do
      declare -g  && shift 2
    done
  

Hyphenated variant (-key1 foo -key2 bar ...) can be parsed by changing "$1"="$2" into "${1#-}"="$2".

~ Tilde

Expands the environment variable $HOME.
(ls ~/Documents is equivalent to: ls $HOME/Documents).

* Globbing

Simple star * expands to files in the working directory matching. Double star** expands files matching pattern in subfolders. Behaviour depends on trailing slash. It does not follow symlinks (bash>=4.3).

$@ Argument Array

Array-like positional parameters, {$1, $2, $3 ...}. Equivalent to $* when un-quotted. When used as an argument and quotted, passes the argument vector as if each was individually quotted.

$(command), or equivalent `command`

Evaluates arithmetic expression, substitutes its value.

$* Argument IFS Expansion

IFS expansion of all positional parameters, $1 $2 $3... meaning all positional parameters separated by the internal field separator. Equivalent to $@ when un-quotted. When used as an argument and quotted, passes the argument vector as a single one.

$# Number of positional parameters

Straightforward, the number of parameters.

  echo 'echo "$#"' > nb.sh && chmod +x nb.sh
  ./nb.sh                    # 0
  ./nb.sh one two three      # 3
  ./nb.sh 'one two three'    # 1
  

$- Current Shell Options

Current options set for the shell, from an interactive shell, should shown the default -himBHs. The extra-s means commands are read from stdin, which became default starting in bash 4.4, the other options are detailed in the table below.


Defaults (bash>=4.4)
Flag Name Explaination
hhashallLocate and remember commands (hash)
iinteractiveInteractive shell
mmonitorMonitor mode, Job control enabled
BbraceexpandPerform brace expansion
HhistexpandPerform !-style history substitution

$$ Current PID

The Process ID of the current shell (not subshell).

$_ Most Recent Parameter

Immediately after startup, set to the absolute path of the command to start the current shell. Then, the value of the most recent parameter used in previous commands.

It is simiar to !$ but resolves the actual value vs. typed value.

  1. Run echo "$(date + %s)", curr. seconds since epoch.
  2. After a few seconds, echo "$_" shows the same value, the seconds since epoch at the time of the previous command, despite the time being now different.
  3. After a few seconds, echo "!$" shows a different value, since it expands to echo "$(date + %s)", and the current time has changed.

$? Most Recent Foreground Exit Status

The exit status value of the most recent foreground pipeline.

$! Most Recent Background PID

The Process ID of the most recent background command.

!! Most Recent Command

This repeats the last command. It has frequent uses:

    # making a script executable
    ./annoyingly/deep/script.sh
    bash: ./annoyingly/deep/script.sh: \
      Permission denied
    chmod +x !!

    # superuser elevation
    mv /1.txt .
    mv: cannot move '/1.txt' to './1.txt': \
      Permission denied
    sudo !!
  

!prefix Most Recent prefix-ed Command

Repeats most recent command prefixed by prefix

!$, or equivalent !!$

Last argument of the preceding command. Slightly different than $_, which provides disambiguation by example.