I am confused by the usage of brackets, parentheses, curly braces in Bash, as well as the difference between their double or single forms. Is there a clear explanation?
Round brackets (also called parentheses, especially in American English) are mainly used to separate off information that isn't essential to the meaning of the rest of the sentence. If you removed the bracketed material the sentence would still make perfectly good sense.
The "{}" are referred to as curly brackets or braces while "<>" are often called angle brackets or braces. The term "curly braces" is more favored in the U.S., while "brackets" is more widely used in British English.
Parentheses are for separating citations or other asides from the body text. Brackets show changes within quoted material. Braces —sometimes known as curly brackets—are not typically used except in technical and mathematical writing.
The four main paired punctuation symbols are the bracket (or square bracket; also called parenthesis in British English), the parenthesis (plural: parentheses), the brace (curly bracket in British English), and the inequality sign (pointy bracket).
In Bash, test
and [
are shell builtins.
The double bracket, which is a shell keyword, enables additional functionality. For example, you can use &&
and ||
instead of -a
and -o
and there's a regular expression matching operator =~
.
Also, in a simple test, double square brackets seem to evaluate quite a lot quicker than single ones.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done real 0m24.548s user 0m24.337s sys 0m0.036s $ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done real 0m33.478s user 0m33.478s sys 0m0.000s
The braces, in addition to delimiting a variable name are used for parameter expansion so you can do things like:
Truncate the contents of a variable
$ var="abcde"; echo ${var%d*} abc
Make substitutions similar to sed
$ var="abcde"; echo ${var/de/12} abc12
Use a default value
$ default="hello"; unset var; echo ${var:-$default} hello
and several more
Also, brace expansions create lists of strings which are typically iterated over in loops:
$ echo f{oo,ee,a}d food feed fad $ mv error.log{,.OLD} (error.log is renamed to error.log.OLD because the brace expression expands to "mv error.log error.log.OLD") $ for num in {000..2}; do echo "$num"; done 000 001 002 $ echo {00..8..2} 00 02 04 06 08 $ echo {D..T..4} D H L P T
Note that the leading zero and increment features weren't available before Bash 4.
Thanks to gboffi for reminding me about brace expansions.
Double parentheses are used for arithmetic operations:
((a++)) ((meaning = 42)) for ((i=0; i<10; i++)) echo $((a + b + (14 * c)))
and they enable you to omit the dollar signs on integer and array variables and include spaces around operators for readability.
Single brackets are also used for array indices:
array[4]="hello" element=${array[index]}
Curly brace are required for (most/all?) array references on the right hand side.
ephemient's comment reminded me that parentheses are also used for subshells. And that they are used to create arrays.
array=(1 2 3) echo ${array[1]} 2
A single bracket ([
) usually actually calls a program named [
; man test
or man [
for more info. Example:
$ VARIABLE=abcdef $ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi yes
The double bracket ([[
) does the same thing (basically) as a single bracket, but is a bash builtin.
$ VARIABLE=abcdef $ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi no
Parentheses (()
) are used to create a subshell. For example:
$ pwd /home/user $ (cd /tmp; pwd) /tmp $ pwd /home/user
As you can see, the subshell allowed you to perform operations without affecting the environment of the current shell.
(a) Braces ({}
) are used to unambiguously identify variables. Example:
$ VARIABLE=abcdef $ echo Variable: $VARIABLE Variable: abcdef $ echo Variable: $VARIABLE123456 Variable: $ echo Variable: ${VARIABLE}123456 Variable: abcdef123456
(b) Braces are also used to execute a sequence of commands in the current shell context, e.g.
$ { date; top -b -n1 | head ; } >logfile # 'date' and 'top' output are concatenated, # could be useful sometimes to hunt for a top loader ) $ { date; make 2>&1; date; } | tee logfile # now we can calculate the duration of a build from the logfile
There is a subtle syntactic difference with ( )
, though (see bash reference) ; essentially, a semicolon ;
after the last command within braces is a must, and the braces {
, }
must be surrounded by spaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With