Master Bash Brackets: Parentheses, Brackets, and Brace Expansions Explained
This guide explains Bash’s various bracket types—single and double parentheses, single and double square brackets, and curly braces—including their syntax, common use cases, command and arithmetic expansions, pattern removal, and practical examples for reliable shell scripting.
1. Parentheses ()
1. Single parentheses ()
① Command grouping: commands inside parentheses run in a subshell, so variables defined there are not available after the group. Separate commands with semicolons; the last command may omit the semicolon.
② Command substitution: equivalent to $(cmd). The shell executes cmd, captures its standard output, and replaces the whole construct with that output. Some shells (e.g., tcsh) do not support this form.
③ Array initialization example: array=(a b c d) 2. Double parentheses (( ))
① Arithmetic expansion: evaluates an integer arithmetic expression; the exit status is 0 for a non‑zero result (true) and 1 for zero (false). Logical expressions follow C syntax.
② Any C‑compatible arithmetic expression can be used, including base‑prefix notation. Example: ((16#5f)) yields 95 (hex to decimal).
③ Variable increment example: a=5; ((a++)) makes a become 6.
④ Commonly used in arithmetic comparisons; variables inside do not need the $ prefix. Multiple expressions can be separated by commas, e.g., for ((i=0;i<5;i++)).
2. Square Brackets []
1. Single brackets []
① In Bash, [ is a synonym for the test builtin. It evaluates a conditional expression and returns an exit status. Modern Bash requires the closing ].
② Comparison operators: == and != for string comparison; numeric comparisons use -eq, -gt, etc. The symbols < and > are not valid for numeric tests.
③ Character class usage in regular expressions, not in test.
④ In array contexts, brackets select an element by index.
2. Double brackets [[ ]]
① [[ is a Bash keyword, not a command. Inside, pathname expansion and word splitting are suppressed, but parameter expansion and command substitution still occur.
② Supports pattern matching with =~ and globbing; patterns need not be quoted.
③ Provides safer conditional syntax; logical operators like &&, ||, <, > work without quoting issues.
④ Returns an exit status based on the evaluated expression.
Example comparisons:
if ( $i<5 )
if [ $i -lt 5 ]
if [ $a -ne 1 -a $a != 2 ]
if [ $a -ne 1 ] && [ $a != 2 ]
if [[ $a != 1 && $a != 2 ]]
for i in $(seq 0 4); do echo $i; done
for i in `seq 0 4`; do echo $i; done
for ((i=0;i<5;i++)); do echo $i; done
for i in {0..4}; do echo $i; done3. Curly Braces { }
1. General usage
① Brace expansion (globbing): generates a list of strings. No spaces are allowed unless escaped. Examples:
# ls {ex1,ex2}.sh
ex1.sh ex2.sh
# ls {ex{1..3},ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
# ls {ex[1-3],ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh② Command grouping with braces creates an anonymous function; commands run in the current shell, so variables remain available. Commands must be separated by semicolons, and a space is required after the opening brace.
2. Parameter substitution forms
${var:-string}, ${var:+string}, ${var:=string}, ${var:?string}• ${var:-string}: use string if var is unset or null. • ${var:+string} : use string only if var is set and non‑null. • ${var:=string} : assign string to var if it is unset or null, then expand to the new value. • ${var:?string} : if var is unset or null, print string to standard error and abort the script. 3. Pattern removal <code>${var%pattern}, ${var%%pattern}, ${var#pattern}, ${var##pattern}</code> Single % or # removes the shortest matching suffix or prefix; double %% or ## removes the longest. Examples with var=testcase : <code># var=testcase
# echo ${var%s*e} # testca
# echo ${var%%s*e} # te
# echo ${var#?e} # stcase
# echo ${var##?e} # stcase
# echo ${var##*e} # (empty)
# echo ${var##*s} # e
# echo ${var##test}# case</code> 4. String extraction and replacement <code>${var:num}, ${var:num1:num2}, ${var/pattern/pattern}, ${var//pattern/pattern}</code> • ${var:num} : extract substring from position num to the end (positive index from the left, negative from the right). • ${var:num1:num2} : extract num2 characters starting at num1 . • ${var/pattern/pattern} : replace first occurrence of pattern . • ${var//pattern/pattern} : replace all occurrences of pattern . Example with var=/home/centos : <code># var=/home/centos
# echo ${var:5} # /centos
# echo ${var:-6} # centos
# echo ${var:1:4} # home
# echo ${var/o/h} # /hhme/centos
# echo ${var//o/h} # /hhme/cenths</code> 4. Dollar‑sign expansions ① ${a} expands to the value of variable a ; braces can be omitted when unambiguous. ② $(cmd) performs command substitution, equivalent to backticks. ③ $((expression)) evaluates an arithmetic expression using C syntax, supporting ternary and logical operators. 5. Practical usage Multiple command execution examples: Single parentheses: (cmd1; cmd2; cmd3) runs in a subshell. Single braces: { cmd1; cmd2; cmd3; } runs in the current shell; a space after the opening brace is required and the final command must end with a semicolon. Redirections inside the group affect only the commands inside; redirections outside affect the whole group.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
