$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 [[ $# -ge 2 ]]; do
      printf -v "$1" '%s' "$2"; shift 2
    done
  

Hyphenated variant (-key1 foo -key2 bar ...) can be parsed by changing "$1" into "${1#-}". printf -v works in any bash, unlike declare -g (bash>=4.2, absent from macOS).

~ Tilde

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

* Globbing

Simple star * expands to the names in the working directory matching the pattern. Double star ** also matches through subdirectories, once enabled with shopt -s globstar (bash>=4); **/ matches directories only. It does not follow symlinks (bash>=4.3).

$@ Argument Array

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

$(command), or equivalent `command`

Command substitution: runs command in a subshell, substitutes its stdout, minus trailing newlines. $(…) nests without escaping, unlike backquotes.

$((expression))

Arithmetic expansion: evaluates an integer expression, substitutes its value. echo $(( 2 ** 10 )) shows 1024.

$* 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 unquoted. When used as an argument and quoted, 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. An interactive shell typically shows himBHs. The s means commands are read from stdin; bash only reports it since bash 4.4 (macOS's bash 3.2 shows himBH). The flags are detailed in the table below.


Defaults
Flag Name Explanation
hhashallLocate and remember commands (hash)
iinteractiveInteractive shell
mmonitorMonitor mode, Job control enabled
BbraceexpandPerform brace expansion
HhistexpandPerform !-style history substitution
sstdinCommands read from stdin

$$ 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 similar to !$ but resolves the expanded value vs. the 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. Had you instead run echo !$, it shows a different value, since it expands to echo "$(date +%s)", re-evaluated with the current time.

$? 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, as typed. Slightly different than $_; see its example for the difference.