Complete Guide to Bash Special Syntax, Variables, and Expansions

Overview

This article provides a comprehensive summary of all special syntax, variables, expansion rules, and control structures used in Bash shell scripting.


Variable Notation

Dynamic or environment-dependent values are denoted as <<variable>>.
All examples below explicitly show their usage.

Variable Example Description
<<var>> name, path, user Arbitrary variable name
<<default>> guest, 8080 Default or fallback value
<<pattern>> *.txt, */ File or string pattern
<<offset>> 0, 3 Starting index of substring (0-based)
<<length>> 4, 10 Length of substring
<<prefix>> ENV_, HOST Prefix pattern for variable names
<<index>> 0, 1, 2 Array or associative key index
<<file>> /tmp/test.txt File path

Step 1: Metacharacters

Symbol Meaning Example
* Matches any string ls *.txt → lists all .txt files
? Matches any single character ls ?.sh → matches a.sh, b.sh
[a-z] Range match ls [A-Z]* → files starting with uppercase
{a,b} Brace expansion mv {hoge,huga}
{1..3} Sequence expansion touch file{1..3}.txt
$ Variable expansion echo $HOME
! (negation) Logical NOT [[ ! -f test.txt ]]
! (history) History expansion !10 → reruns command #10
~ Home directory cd ~
; Command separator pwd; ls
&& Execute if previous succeeded make && echo OK
` `
& Run in background sleep 5 &
` ` Pipe output
> Redirect stdout echo hi > out.txt
>> Append output echo hi >> out.txt
< Redirect stdin wc -l < file.txt
() Subshell (cd /tmp; ls)
{} Same shell block { echo A; echo B; }
\ Escape character echo \$HOME
' ' Literal (no expansion) echo '$USER'
" " Expand variables echo "$USER"

Step 2: Special Variables

Variable Description Example
$0 Script name echo $0script.sh
$1–$9 Positional args echo $1
$@ All args as array for a in "$@"; do echo $a; done
$# Arg count echo $#
$? Last exit status ls /nope; echo $?
$$ Current PID echo $$
$! Last BG job PID sleep 10 & echo $!
$- Current shell options echo $-
$_ Last arg of previous cmd echo $_
$PPID Parent PID echo $PPID
$RANDOM Random number echo $RANDOM
$SECONDS Seconds since shell start echo $SECONDS
$FUNCNAME Function name f(){ echo $FUNCNAME; }; f
$PIPESTATUS[@] Exit status of pipe cmds `ls

Step 3: Parameter Expansion

Syntax Description Example
${<<var>>} Variable expansion name=user; echo ${name}
${<<var>>:-<<default>>} Use default if unset echo ${user:-guest}
${<<var>>:=<<default>>} Assign default if unset echo ${port:=8080}
${<<var>>:+alt} Use alt if set x=1; echo ${x:+OK}
${<<var>>:?msg} Error if unset echo ${config:?missing}
${#<<var>>} String length name=user; echo ${#name}
${<<var>>%<<pattern>>} Remove shortest suffix path=/a/b/c; echo ${path%/*}
${<<var>>%%<<pattern>>} Remove longest suffix echo ${path%%/*}
${<<var>>#<<pattern>>} Remove shortest prefix echo ${path#*/}
${<<var>>##<<pattern>>} Remove longest prefix echo ${path##*/}
${<<var>>/<<pattern>>/<<repl>>} Replace first match echo ${msg/foo/bar}
${<<var>>//<<pattern>>/<<repl>>} Replace all echo ${msg// /_}
${<<var>>:<<offset>>} Substring from offset s=abcdef; echo ${s:2}
${<<var>>:<<offset>>:<<length>>} Substring with length echo ${s:1:3}
${!<<prefix>>*} Vars with prefix HOST1=x; HOST2=y; echo ${!HOST*}
${!<<var>>} Indirect reference ref=NAME; NAME=user; echo ${!ref}
${<<var>>,} / ${<<var>>^^} Case conversion n=abc; echo ${n^^}
${<<var>>@Q} Quoted form x='abc'; echo ${x@Q}

Step 4: Arrays and Associative Arrays

arr=(a b c)
echo ${arr[<<index>>]}     # Access element
echo ${#arr[@]}            # Count
for i in "${arr[@]}"; do echo $i; done

declare -A map
map[<<index>>]=100
map[name]=user
echo ${map[<<index>>]}     # Value
echo ${!map[@]}            # Keys

Step 5: Arithmetic Expansion

x=5; y=3
echo $((x + y))   # 8
((x *= 2))
echo $x           # 10

Step 6: Conditions and Comparisons

if [ "$USER" = "root" ]; then echo root; fi
if [ "$x" -lt 10 ]; then echo small; fi
if [ -f /etc/passwd ]; then echo exists; fi
s="hello123"
[[ $s =~ [0-9]+ ]] && echo "has number"

Step 7: Command Substitution and Subshells

echo "Today: $(date +%Y-%m-%d)"
(cd /tmp; ls)

Step 8: Redirection and File Descriptors

echo "Hello" > <<file>>
echo "Append" >> <<file>>
wc -l < <<file>>
ls /nope 2> err.log
echo "Error" >&2
exec 3> custom.log
echo "via fd3" >&3
exec 3>&-

File Descriptor Reference

FD Name Description Example
0 stdin Input < file.txt
1 stdout Normal output echo test > out.txt
2 stderr Error output ls /nope 2> err.log
3+ Custom User-defined streams exec 3> log.txt

FD3 is a custom descriptor:

exec 3> process.log
echo "start" >&3
exec 3>&-

Step 9: Traps and Error Handling

set -e
set -u
set -x
set -o pipefail

trap 'echo done' EXIT
trap 'echo error' ERR

Step 10: Job Control

sleep 10 &
jobs
fg %1
bg %1
disown %1
kill %1

Job Reference (%1)

Example:

sleep 60 &
jobs

Output:

[1]+ Running sleep 60 &
Symbol Meaning
%1 Job ID 1
%+ Current job
%- Previous job

Step 11: Reserved Commands

:        # No-op
true
false
source ~/.bashrc
eval "echo executed"
{ echo A; echo B; }

Summary

This guide comprehensively covered Bash’s special syntax, expansions, variables, metacharacters, and control structures.
Understanding these concepts enables you to write safe, reusable, and automation-ready shell scripts.