Bash Syntax Reference

This page is meant as a reference, to be searched. If you encounter an unfamiliar piece of bash syntax, you can look it up here to find out what it means. As such, it's more useful to people who are trying to read a script (which someone else wrote), rather than trying to write one.

If you're trying to write a new bash script, other resources include BashGuide, BashSheet, BashPitfalls and BashProgramming.

The sheer number of combinations of syntax characters in bash is massive, so this list may be incomplete.

Syntax

Example

Explanation

~

cd ~/bin

TildeExpansion, resulting in the current user's home directory.

~

mode=$((mode & ~umask))

In an ArithmeticExpression, bitwise NOT.

~user

cd ~john

Expands to the home directory of user.

~-

cd foo/bar && tar xf ~-/file.tar

Expands to the previous directory (same as "$OLDPWD")

~+

printf 'pwd: %s\n' ~+

Expands to the current directory (same as "$PWD")

~number

pushd /usr; pushd /tmp; ls ~+1

Expands to the nth entry of the dirstack (same as "$(dirs +n)" and "$(dirs -n)")

`

eval `resize`

Deprecated form of CommandSubstitution. See BashFAQ/082.

!

if ! myfunc; then myerrorhandler; fi

Reverses the exit status of a pipeline.

!

[[ ! -d $d ]]

Inside [[ or [ or test, negates the following expression.

!

((! verbose))

In an ArithmeticExpression, negates the result of the following expression.

!

echo [!x]*

As the first character inside a [...] in a glob, reverses the set of matched characters.

!=

[ "$input" != y ]

In a test or [ command, string comparison, not equal.

!=

[[ $input != [Yy] ]]

In a [[ command, a glob pattern or string comparison, not equal.

!=

(( x != 42 ))

In an ArithmeticExpression, integer comparison, not equal.

!!

!!

Repeat the previous command. (Only if HistoryExpansion is enabled.)

!word

!make

Repeat the previous command starting with word (if history expansion is enabled).

!-number

!-3

Repeat the command number entries in the past (if history expansion is enabled).

$!

myjob & pid=$!

Expands to the process ID of the most recent background pipeline.

${!var}

local arg2="${!2}"

Indirect parameter expansion; uses the value of var as a variable name and expands it.

${!arr[@]}

for i in "${!arr[@]}"

Expands to all indices of an indexed or associative array variable. The double quotes are required for associative arrays.

!(patterns)

rsync -a !(*~) "$dest"

Extended glob which matches all strings/files not matching the patterns.

"$@"

exec foo "$@"

Expands to all positional parameters, like "$1" "$2" .... The double quotes are required.

"${arr[@]}"

find "${args[@]}"

Expands to all values in an indexed array variable. The double quotes are required.

${!prefix@}

echo "${!BASH@}"

Expands to the names of variables beginning with prefix.

${var@Q}

ssh host "rm ${file@Q}"

Expands var in a quoted form which can be used in a raw bash command.

@(patterns)

[[ $input = @(foo|bar) ]]

Extended glob which matches all strings/files that match any of the patterns.

#

# look for serial number

Any word beginning with # starts a comment; the rest of the line is ignored.

$#

if (($# < 2)); then usage; fi

Expands to the number of positional parameters.

${var#prefix}

var=${var#?}

Expands to the value of var with the shortest prefix removed if present.

${var##prefix}

base=${file##*/}

Expands to the value of var with the longest prefix removed if present.

${#var}

len=${#string}

Expands to the length of var in characters (not bytes unless in the C or POSIX locale).

${#arr[@]}

size=${#arr[@]}

Expands to the number of values in an indexed or associative array variable.

$

[[ $serial =~ x[0-9]+$ ]]

In a basic/extended regular expression, matches the end of the input. Also called an anchor.

$$

kill -INT $$

Expands to the process ID of the current shell (never a subshell).

$var

cd "$foo" || exit

Expands to the value of the variable var.

${var}

echo "I like ${fruit}s"

Expands to the value of the variable var. Not a substitute for Quotes.

$(cmd)

output=$(cmd)

CommandSubstitution, expands to the standard output of cmd.

$((exp))

i=$((i+1))

ArithmeticExpression, expands to the value of exp evaluated in a math context.

%

r=$((i % 4))

In a math context, remainder (modulus).

%=

((i %= 4))

In a math context, assign a new value to a variable after performing modulus with the variable and a value.

${var%suffix}

dir=${file%/*}

Expands to the value of var with the shortest suffix removed if present.

${var%%suffix}

major=${version%%.*}

Expands to the value of var with the longest suffix removed if present.

^

if foo ^ grep bar >/dev/null

Synonym for | in the Bourne shell only (not bash or POSIX sh).

^

[[ $serial =~ ^[0-9]+z ]]

In a basic/extended regular expression, matches the start of the input. Also called an anchor.

^

[[ $n =~ [^0-9] ]]

As the first character inside a [...] in a basic/extended regular expression, reverses the set of matched characters.

^

echo [^x]*

As the first character inside a [...] in a glob, reverses the set of matched characters. Not POSIX.

^

x=$((y ^ 0xff))

In an ArithmeticExpression, bitwise XOR (exclusive OR).

^=

((y ^= 0xff))

In an ArithmeticExpression, assign a new value to a variable after performing bitwise XOR.

${var^}

echo "${name^}"

Expands to the value of var with the first character capitalized.

${var^pattern}

echo "${name^[aeiou]}"

Expands to the value of var with the first character capitalized only if it matches pattern.

${arr[@]^}

echo "${title[@]^}"

Expands to the values of an indexed or associative array variable with the first character of each value capitalized.

${arr[@]^pattern}

echo "${title[@]^[aeiou]}"

Expands to the values of an array variable with first characters capitalized if they match pattern.

${var^^}

caps=${name^^}

Expands to the value of var with all characters capitalized.

${var^^pattern}

var=${var^^[aeiou]}

Expands to the value of var with all characters which match pattern capitalized.

${arr[@]^^}

caps=("${arr[@]^^}")

Expands to the values of an indexed or associative array variable with all characters capitalized.

${arr[@]^^pattern}

silly=("${arr[@]^^[aeiou]}")

Expands to the values of an array variable with all characters matching pattern capitalized.

^old^new^

^.txzt^.txt^

Repeat the previous command replacing old with new (only if history expansion is enabled).

&

updatedb &

Run a pipeline in the background.

&

mode=$((mode & ~umask))

In an ArithmeticExpression, bitwise AND.

&=

((mode &= ~umask))

In an ArithmeticExpression, assign a new value to a variable after performing bitwise AND.

&&

[[ -e ~/.bashrc ]] && . ~/.bashrc

Execute the next command only if the previous command succeeded (exit status 0).

&&

(( i > 4 && i < 10 ))

In an ArithmeticExpression, logical AND.

&&

[[ -d $dir && ! -L $dir ]]

In [[, between expressions, logical AND.

*

rm *.bak

In a glob, matches any string (including the empty string).

*

[[ $serial =~ -([0-9]*)- ]]

In a basic/extended regular expression, matches 0 or more of the previous token.

*

i=$((x * y))

In a math context, multiplication.

*=

((x *= 3))

In a math context, multiply a variable by a value.

**

pow=$((2 ** n))

In a math context, exponentiation ("power").

**

for f in **/*.txt

If globstar is enabled, matches all files/directories (recursively).

"$*"

printf '%s\n' "$*"

Expands to a single string containing all positional parameters, with the first character of IFS between them. The quotes are required.

"${arr[*]}"

printf '%s\n' "${words[*]}"

Expands to a single string containing all values of an indexed or associative array variable, with the first character of IFS between them. The quotes are required.

(

[[ ( $a = 1 || $b = 2 ) && $c = 3 ]]

Inside [[, parentheses allow grouping to change operator precedence.

*(patterns)

var=${var##*([[:space:]])}

In an extended glob, matches 0 or more instances of the patterns.

(

[[ $line =~ foo-(bar[0-9]+) ]]

In an extended regular expression, serves two purposes: grouping, and capture grouping. In [[, captured groups are exposed in the BASH_REMATCH array variable.

\(

sed 's/a\(b[0-9]\)/c\1/'

In a basic regular expression, capture grouping. Bash does not use basic regular expressions, so this is exclusively for external commands which do, such as sed.

(cmd)

(cd "$dir" && make)

Execute cmd in a SubShell.

((exp))

((i++))

Evaluate exp as an ArithmeticExpression and exit 0 if the value is non-zero (true), or 1 if the value is 0 (false).

for ((start;cond;step))

for ((i=0; i<10; i++))

C-style for loop. start, cond and step are evaluated in math contexts.

func()

f() { ...; }

Define function func.

_

read -r var1 _

Not actually syntax, _ is simply a special parameter name. Assignments to _ do nothing, so it's common to use _ to absorb extra data fields that aren't needed.

$_

mkdir /long/path && cd "$_"

The special parameter _ holds the last argument of the previous command.

-

i=$((i - 2))

In a math context, subtraction.

-

vi foo[0-9].txt

In a glob or extended regular expression, [a-b] matches characters in the range from a to b in the current locale. Extremely unwise to use with letters outside of the C/POSIX locale. Digits tend to be safe. Remember that it's only digits, not numbers.

-

cat - file2

Not actually shell syntax. By convention, many commands that expect filenames allow - to be specified to mean standard input or standard output.

-

f() { local -; ...; }

A special case for the local builtin. When - is passed as an argument to the local builtin, any options changed by set (such as set -f, set -o pipefail) will be local to the function. It's meant to signify that $- is made local, but also applies to options without single letter alternative.

$-

if [[ $- = *i* ]]; then

The special parameter - holds all of the single-letter set options that are currently enabled.

--

rm -- "$file"

Not actually shell syntax. Signifies the end of options to most commands. If the $file begins with -, rm will not treat it as another cluster of options.

--

((i--))

In a math context, post-decrement or pre-decrement (subtracts one from a variable's value, and returns either the previous or new value, respectively).

${var-default}

${PAGER-more}

Expand a parameter, but use a default value if the parameter is unset.

${var:-default}

${PAGER:-more}

Expand a parameter, but use a default value if the parameter is unset or contains the empty string.

-=

((i -= 3))

In a math context, decrement a variable by a value.

+

i=$((i + 3))

In a math context, addition.

+

[[ $f =~ foo[0-9]+bar ]]

In an extended regular expression, matches one or more instances of the previous token. Equivalent to \{1,\} in a basic regular expression.

${var+words}

[[ ${var+set} ]]

Expand to words if the var is set to any value; otherwise, expand to nothing.

${var:+words}

mailx ${subject:+"-s$subject"} "$rcpt"

Expand to words if the var is set to any non-empty value; otherwise, expand to nothing.

++

((i++))

In a math context, post-increment or pre-increment (adds one to a variable's value, and returns either the previous or new value, respectively).

+=

((i += 3))

In a math context, increment a variable by a value.

var+=value

output+=$line$'\n'

Appends value to the string variable var.

arr+=(words)

args+=(-o -iname "*.$ext")

Appends words to the array variable arr.

+(patterns)

var=${var##+([[:space:]])

As an extended glob, matches one or more instances of patterns.

=

[ "$input" = "" ]

In a test or [ command, string comparison.

=

[[ $input = [Yy]* ]]

In a [[ command, a glob-pattern or string comparison. Any quoted characters on the right hand side are treated as literal.

var=value

x=42

Assigns value to the string variable var.

${var=default}

: "${EDITOR=nano}"

Expands var, but if var is unset, the default value is assigned to it first.

${var:=default}

: "${EDITOR:=nano}"

Expands var, but if var is unset or contains the empty string, the default value is assigned to it first.

==

[[ $input == [Yy]* ]]

In a [[ command, a glob-pattern or string comparison. Identical to =.

==

if ((i == 3))

In a math context, integer comparison.

=~

[[ $input =~ $regex ]]

In a [[ command, match against an extended regular expression. Any quoted characters on the right hand side are treated as literal.

{ cmds }

f() { echo "f"; }

Command grouping, not a SubShell. Allows cmds to be placed anywhere a single command would normally go.

{n}

[[ $x =~ foo-[0-9]{3}-bar ]]

In an extended regular expression, matches n instances of the previous token. Equivalent to \{n\} in a basic regular expression.

{m,n}

[[ $x =~ foo-[0-9]{1,3}-bar ]]

In an extended regular expression, matches between m and n instances of the previous token. If n is omitted, treat it as infinity. Equivalent to \{m,n\} in a basic regular expression.

{string,string}

vi foo.{h,cxx}

BraceExpansion. Generates a list of words consisting of each string together with any prefix/suffix. This is not globbing; it does not check for the existence of files.

{number..number}

for i in {1..10}

BraceExpansion with a numeric range generates a list of words consisting of each number in the range, with optional prefix/suffix.

{number..number..step}

for i in {0..100..10}

BraceExpansion with a numeric range with a step value other than 1.

{letter..letter}

letters=( {A..Z} )

BraceExpansion with a range of letters generates a list of words consisting of each letter in the range, with optional prefix/suffix.

[chars]

rm foo[1246].txt

In a glob or basic/extended regular expression, matches any one character from chars.

[[:class:]]

var=${var##+([[:space:]])}

In a glob or basic/extended regular expression, matches any one character from the character class.

arr[index]=value

seen[$file]=1

Assigns value to the indexth element of the indexed or associative array variable arr. index is evaluated in a math context if the array is indexed.

${arr[index]}

first=${files[0]}

Expands to the indexth element of the indexed or associative array variable arr.

$[

i=$[ "$i" + 1 ]

Obsolete arithmetic expression syntax. Use $(( )) instead.

|

ls -l | more

Pipeline. The standard output of the left side is connected to the standard input of the right side.

|

bits=$((bits | 0x04))

In a math context, bitwise OR.

|

vi foo@(bar|baz).txt

In an extended glob, separates patterns within a single matching expression.

|

case $1 in -h | --help) usage ;; esac

In a case statement, separates patterns within a pattern list.

|

[[ $x =~ foo|bar ]]

In an extended regular expression, matches either of two smaller regular expressions. Has no equivalent in basic regular expressions.

|=

((flags |= 1))

In an ArithmeticExpression, assign a new value to a variable after performing bitwise OR.

|&

make |& less

Pipeline carrying standard output + standard error. Equivalent to 2>&1 |.

||

cd "$foo" || exit

Execute the second command if the first command failed (exit status nonzero).

||

(( i < 0 || i > 99 ))

In an ArithmeticExpression, logical OR.

||

[[ $a = 1 || $b = 2 ]]

In [[, logical OR.

\

sed -e 'something' \

At the end of a line, indicates that the command continues on the next line. The backslash + newline pair are removed.

\

echo "\$4.00"

In many contexts, backslash quotes or escapes the next character, removing its special meaning.

\num

sed 's/\(a[0-9]*\)\1//'

In a basic regular expression, refers to the numth capture group. Bash does not use basic regular expressions, but some external commands do, such as sed.

${var:start}

sub=${input:k}

Expands to the substring of var beginning at start, which is evaluated in a math context, zero-indexed.

${var:start:len}

c=${input:i:1}

Expands to the substring of var beginning at start and a maximum of len characters long. Both start and len are evaluated in math contexts.

;

sleep 30; play alarm.wav

Execute the second command when the first has finished, regardless of exit status.

;;

case $i in q) exit;;

Indicates the end of a command list in a case statement.

;&

case $i in a) a=1;&

Indicates the end of a command list in a case statement, but the next command list is also executed without checking the next pattern.

;;&

case $i in a) a=1;;&

Indicates the end of a command list in a case statement, but the next pattern is also checked.

"

vi "$file"

Quoting but with certain substitutions allowed.

'

vi 'my file'

Quoting with no substitutions.

$'

IFS=$' \t\n'

Quoting with only specific backslash + letter combinations substituted.

$"

printf %s\\n $"An error message"

Indicates a string to be translated. Not secure.

<

if [[ $date < 2020-01-01 ]]

In a [[ command, string (lexical) less-than comparison.

<

while ((i < 10))

In a math context, numerically (integer) less than.

<<

shifted=$((input << n))

In a math context, bitwise left shift.

<<=

((n <<= 2))

In a math context, modify a variable by bitwise left shifting.

<file

read -r pid < "$pidfile"

Standard input redirection from file.

<<delim

cat <<'EOF'

Here document. Standard input is redirected from the following lines of the script, until delim as a standalone line. If any character of delim is quoted, no substitutions are preformed in the here document. Otherwise, some substitutions occur.

<<-delim

cat <<-EOF

Here document. Standard input is redirected from the following lines with leading tabs removed. See above for more details.

<<<word

read -ra arr <<< "$line"

Here string. Standard input is redirected from word plus a newline.

<(cmd)

mapfile -t arr < <(foo)

ProcessSubstitution. cmd is executed as a background process, and the syntax is replaced by a FIFO-equivalent from which the command's standard output may be read.

>(cmd)

exec > >(timestamper)

ProcessSubstitution. cmd is executed as a background process, and the syntax is replaced by a FIFO-equivalent. The standard input of cmd is redirected from this FIFO-equivalent.

n<file

while ... done 3< file

Redirect input FileDescriptor n from file.

n<&m

exec 3<&0

Duplicate FileDescriptor m as file descriptor n.

n<&-

exec 3<&-

Close FileDescriptor n.

{var}<file

exec {fd}<file; read -r -u "$fd" line

Open file for reading. Bash allocates a FileDescriptor and stores it in var.

{var}<&m

exec {fd}<&0

Duplicate FileDescriptor m. The new file descriptor number is assigned to var.

{var}<&-

exec {fd}<&-

Close FileDescriptor whose value is stored in the variable var.

>

if [[ $date > 1979-12-31 ]]

In a [[ command, string (lexical) greater-than comparison.

>

while ((i > 0))

In a math context, numerically (integer) greater than.

>>

shifted=$((input >> n))

In a math context, bitwise right shift.

>>=

((n >>= 2))

In a math context, modify a variable by bitwise right shifting.

>file

foo >/dev/null

Redirect standard output to file.

>>file

foo >> logfile

Redirect standard output to file in append mode.

&>file

foo &>/dev/null

Redirect standard output and standard error to file. Equivalent to >file 2>&1.

>&file

foo >&/dev/null

Redirect standard output and standard error to file. Equivalent to >file 2>&1. However, if file expands to a number or -, a different redirection is performed. Not recommended.

&>>file

foo &>> logfile

Redirect standard output and standard error to file in append mode. Equivalent to >>file 2>&1.

n>file

exec 3> >(timestamper)

Redirect output FileDescriptor n to file.

n>>file

set -x; exec 2>> logfile

Redirect output FileDescriptor n to file in append mode.

n>&m

foo >> logfile 2>&1

Duplicate FileDescriptor m as file descriptor n.

n>&-

exec 3>&-

Close FileDescriptor n.

{var}>file

exec {BASH_XTRACEFD}>xtrace.log; set -x

Open file for writing. Bash allocates a file descriptor and stores it in var

{var}>>file

exec {BASH_XTRACEFD}>>xtrace.log; set -x

Open file in append mode. Bash allocates a file descriptor and stores it in var

{var}>&m

exec {fd}>&1

Duplicate FileDescriptor m. The new file descriptor number is assigned to var.

{var}>&-

exec {fd}>&-

Close FileDescriptor whose value is stored in the variable var.

<>file

exec <>/dev/tcp/"$host"/80

Open file as FileDescriptor 0 (standard input) for reading and writing. Normally the form with a FD number would be used (see below).

n<>file

exec 3<>/dev/tcp/"$host"/80

Open file as FileDescriptor n for reading and writing. Useful with network sockets.

{var}<>file

exec {httpfd}<>/dev/tcp/example.com/80

Open file for reading and writing. Bash allocates a file descriptor and stores it in var

,

((a=0, b=1))

In a math context, comma separates different expressions.

.

. ~/.bashrc

Synonym for the source builtin command.

..

cd ..

Refers to the parent directory. Not precisely shell syntax.

?

vi foo-??.c

In a glob, matches any single character. Equivalent to . in a basic/extended regular expression.

?

[[ $file =~ \.txt~?$ ]]

In an extended regular expression, matches 0 or 1 instance of the previous token. Equivalent to \{0,1\} in a basic regular expression.

$?

cmd; res=$?

Expands to the exit status (integer between 0-255, inclusive) of the last command.

expr?exp2:exp3

x=$((i>0 ? 3 : 5))

In a math context, the same as C's ternary conditional operator. Only integer expressions are allowed, not strings.

/

n=$((COLUMNS / 8))

In a math context, integer division.

/=

((n /= 2))

In a math context, divide a variable by a value (integer division).

${var/search}

x=${x/junk}

Expands to the value of var with the first instance of search (a glob) removed. Degenerate/simplified form of ${var/search/replace} with an implied empty replace string.

${var//search}

x=${x//junk}

Expands to the value of var with all instances of search (a glob) removed. Degenerate/simplified form of ${var//search/replace} with an implied empty replace string.

${var/search/replace}

x=${x/foo/bar}

Expands to the value of var with the first instance of search (a glob) replaced by replace.

${var//search/replace}

x=${x//foo/bar}

Expands to the value of var with all instances of search (a glob) replaced by replace.


CategoryShell

BashSyntaxReference (last edited 2022-10-16 15:28:22 by geirha)