bash: variablesShell variables: assign, quote, default and export
Variables hold the values a script works with: names, versions, paths, command output. Bash has strict rules: no spaces around =, $name expands, double quotes keep spaces safe, single quotes keep everything literal, ${var:-default} fills gaps and export passes a variable to child processes.
name=value "$name" ${name:-default} ${name:?error} $(command) $((expr)) export nameA release script needs to build an image name and a release directory from a few pieces.
imageLetters, digits and _, not starting with a digit. Lowercase for script variables avoids clashing with env vars like PATH.
A shell variable is a name-to-string entry in the bash process's own memory. Expansion happens before a command runs: bash scans the line, replaces $name and ${...} with values, runs $(...) in a subshell and captures its output, evaluates $((...)) as integer arithmetic, and then, for anything not inside double quotes, performs word splitting on spaces, tabs and newlines (IFS) and glob expansion of * and ?. That last step is why an unquoted $file containing 'weekly report.txt' turns into two arguments. Variables are local to the shell by default. export marks a variable so that bash copies it into the environment block it passes to execve() when it starts a program; children get a copy, and nothing a child does can change the parent's variables. VAR=value command sets a variable in that one command's environment only.
name=valueAssign (no spaces around =); quote values with spaces: msg="disk full""$name"Expand safely: one word, no globbing. Quote almost every expansion'text'Single quotes: nothing expands, $ and \ are literal${name:-def}Value, or def if unset/empty (${name:=def} also assigns it)${name:?msg}Value, or print msg and exit the script if unset/empty$(cmd)Command substitution: the command's output as a value$((a + b))Integer arithmetic (no floats); variables need no $ inside${#name}Length of the value in characters${name##*/} ${name%.*}Strip the longest prefix / shortest suffix matching a pattern${name/old/new}Replace the first match (// for all matches)${name,,} ${name^^}Lowercase / uppercase the value (bash 4+)export namePass the variable to child processes' environmentreadonly nameMake it a constant; later assignments failname = "orders-api"With spaces bash runs a command called name with arguments = and orders-api: 'name: command not found'.
name="orders-api"rm -rf $dir/* with dir unset or misspelledAn empty $dir turns this into rm -rf /*. Unquoted, empty and unchecked variables in destructive commands are a classic outage.
rm -rf "${dir:?dir is not set}"/*echo '$HOME is my home'Single quotes stop all expansion, so it prints the literal text $HOME.
echo "$HOME is my home"total=$a+$bBash variables are strings; this produces the text 5+10, not 15.
total=$((a + b))Setting PATH=/opt/tool/bin in a script and wondering why ls stops workingAssigning replaces the whole value. You removed /usr/bin from the search path.
export PATH="/opt/tool/bin:$PATH"Try these on a Linux machine of your own. Each task has a hint and a solution.
Create a variable app with the value orders-api and print 'Deploying orders-api now' using it.
Print the file name (without directory) and the directory of /var/log/app/app.log.1 using only parameter expansion.
Print the value of ENVIRONMENT, or 'dev' if it isn't set, without setting it.
Show that an unexported variable is invisible to a child bash, then export it and show it again.
bash: variablesShell variables: assign, quote, default and export
Variables hold the values a script works with: names, versions, paths, command output. Bash has strict rules: no spaces around =, $name expands, double quotes keep spaces safe, single quotes keep everything literal, ${var:-default} fills gaps and export passes a variable to child processes.
name=value "$name" ${name:-default} ${name:?error} $(command) $((expr)) export nameA release script needs to build an image name and a release directory from a few pieces.
imageLetters, digits and _, not starting with a digit. Lowercase for script variables avoids clashing with env vars like PATH.
A shell variable is a name-to-string entry in the bash process's own memory. Expansion happens before a command runs: bash scans the line, replaces $name and ${...} with values, runs $(...) in a subshell and captures its output, evaluates $((...)) as integer arithmetic, and then, for anything not inside double quotes, performs word splitting on spaces, tabs and newlines (IFS) and glob expansion of * and ?. That last step is why an unquoted $file containing 'weekly report.txt' turns into two arguments. Variables are local to the shell by default. export marks a variable so that bash copies it into the environment block it passes to execve() when it starts a program; children get a copy, and nothing a child does can change the parent's variables. VAR=value command sets a variable in that one command's environment only.
name=valueAssign (no spaces around =); quote values with spaces: msg="disk full""$name"Expand safely: one word, no globbing. Quote almost every expansion'text'Single quotes: nothing expands, $ and \ are literal${name:-def}Value, or def if unset/empty (${name:=def} also assigns it)${name:?msg}Value, or print msg and exit the script if unset/empty$(cmd)Command substitution: the command's output as a value$((a + b))Integer arithmetic (no floats); variables need no $ inside${#name}Length of the value in characters${name##*/} ${name%.*}Strip the longest prefix / shortest suffix matching a pattern${name/old/new}Replace the first match (// for all matches)${name,,} ${name^^}Lowercase / uppercase the value (bash 4+)export namePass the variable to child processes' environmentreadonly nameMake it a constant; later assignments failname = "orders-api"With spaces bash runs a command called name with arguments = and orders-api: 'name: command not found'.
name="orders-api"rm -rf $dir/* with dir unset or misspelledAn empty $dir turns this into rm -rf /*. Unquoted, empty and unchecked variables in destructive commands are a classic outage.
rm -rf "${dir:?dir is not set}"/*echo '$HOME is my home'Single quotes stop all expansion, so it prints the literal text $HOME.
echo "$HOME is my home"total=$a+$bBash variables are strings; this produces the text 5+10, not 15.
total=$((a + b))Setting PATH=/opt/tool/bin in a script and wondering why ls stops workingAssigning replaces the whole value. You removed /usr/bin from the search path.
export PATH="/opt/tool/bin:$PATH"Try these on a Linux machine of your own. Each task has a hint and a solution.
Create a variable app with the value orders-api and print 'Deploying orders-api now' using it.
Print the file name (without directory) and the directory of /var/log/app/app.log.1 using only parameter expansion.
Print the value of ENVIRONMENT, or 'dev' if it isn't set, without setting it.
Show that an unexported variable is invisible to a child bash, then export it and show it again.