Bash Cheatsheet
Variables
Use this Bash reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Assignment and Declaration
name="Alice" # assign (no spaces around =) age=30 # numbers are strings too readonly PI=3.14 # read-only variable declare -r CONST=42 # same as readonly declare -i num=10 # integer variable (arithmetic forced) declare -l lower="HELLO" # auto-lowercase: lower="hello" declare -u upper="hello" # auto-uppercase: upper="HELLO" declare -x PATH # mark for export (same as export) declare -p varname # print declaration of variable unset varname # delete variable
Accessing Variables
echo $name # basic expansion echo ${name} # braces — required before letters/digits echo "${name}" # always quote to prevent word splitting echo "${name}suffix" # concatenate suffix echo "Value: ${age}" # embed in string # Undefined vs empty echo ${undef} # empty string (no error by default) echo ${undef:-"default"} # use default if unset or empty
Parameter Expansion — Defaults and Fallbacks
| Syntax | Behavior |
|---|---|
${var:-default} | Use default if var unset or empty |
${var-default} | Use default if var unset (not if empty) |
${var:=default} | Assign default to var if unset or empty |
${var:?msg} | Error with msg if var unset or empty |
${var:+other} | Use other if var IS set and non-empty |
echo ${name:-"stranger"} # "stranger" if name is unset/empty : ${config:="/etc/app.conf"} # set default silently echo ${required:?"required is not set"} # abort if missing echo ${debug:+"--verbose"} # only add flag if debug is set
String Length and Slicing
str="Hello, World" echo ${#str} # length: 12 echo ${str:7} # from index 7: "World" echo ${str:7:5} # from index 7, length 5: "World" echo ${str: -5} # last 5 characters (space before -) echo ${str: -5:3} # 3 chars starting 5 from end: "Wor"
Pattern Removal (Prefix / Suffix)
file="path/to/file.tar.gz" echo ${file#*/} # remove shortest prefix matching */ → "to/file.tar.gz" echo ${file##*/} # remove longest prefix matching */ → "file.tar.gz" echo ${file%.*} # remove shortest suffix matching .* → "path/to/file.tar" echo ${file%%.*} # remove longest suffix matching .* → "path/to/file" # Common idiom: extract filename and extension base="${file##*/}" # "file.tar.gz" noext="${base%%.*}" # "file" ext="${file##*.}" # "gz" dir="${file%/*}" # "path/to"
Pattern Substitution
str="foo bar foo baz" echo ${str/foo/FOO} # replace first occurrence: "FOO bar foo baz" echo ${str//foo/FOO} # replace all occurrences: "FOO bar FOO baz" echo ${str/#foo/FOO} # replace if at start: "FOO bar foo baz" echo ${str/%baz/BAZ} # replace if at end: "foo bar foo BAZ" # Delete by replacing with empty string echo ${str/foo/} # " bar foo baz" echo ${str//foo/} # " bar baz"
Case Conversion (Bash 4+)
str="Hello World" echo ${str,,} # all lowercase: "hello world" echo ${str^^} # all uppercase: "HELLO WORLD" echo ${str,} # first char lowercase: "hello World" echo ${str^} # first char uppercase: "Hello World" # With a pattern echo ${str,,[ ]} # lowercase only space chars (rarely useful)
Indirect Expansion
key="name" name="Alice" echo ${!key} # → "Alice" (value of variable named by $key) # List variables matching a prefix echo ${!BASH*} # BASH BASH_VERSION BASH_SOURCE … declare -p ${!BASH*} # print declarations for all BASH* vars
Arithmetic with Variables
declare -i n=5 n+=3 # n is now 8 (integer context) (( x = 10 + 5 )) # arithmetic evaluation (( x++ )) # post-increment (( x-- )) # post-decrement (( x *= 2 )) # multiply in-place x=$(( 10 / 3 )) # integer division → 3 x=$(( 10 % 3 )) # modulo → 1 x=$(( 2 ** 8 )) # exponent → 256
Environment Variables
export VAR="value" # export to child processes export -n VAR # un-export (keep variable, remove from env) printenv # print all environment variables printenv PATH # print a specific env var env # print env (also used to run with modified env) env VAR=val cmd # run cmd with extra env var, without exporting # Common env vars HOME, PATH, USER, SHELL, PWD, OLDPWD, HOSTNAME LANG, LC_ALL, TZ EDITOR, VISUAL, PAGER TMPDIR, XDG_DATA_HOME
Arrays as Variables
arr=(one two three) # indexed array declare -A map # associative array map[key]="value" echo ${arr[0]} # first element echo ${#arr[@]} # array length
See the Arrays page for full array variable syntax.
Variable Scope
# Variables are global to the function unless declared local outer="global" myfunc() { local inner="local" # only visible inside myfunc echo $outer # can read globals outer="modified" # modifies the global } myfunc echo $inner # empty — gone after function returns echo $outer # "modified" # Subshells get a COPY — changes don't propagate up (export TEMP="subshell"; echo $TEMP) echo $TEMP # empty in parent
nameref (Bash 4.3+)
declare -n ref=varname # ref is an alias for varname varname="hello" echo $ref # "hello" ref="world" echo $varname # "world" # Useful for passing variable names to functions set_value() { declare -n _target=$1 _target="$2" } set_value myvar "42" echo $myvar # "42"