Linux / Basic: command-line foundations / Lesson 6
Control the shell environment and expansion
Use variables, exported environments, quoting, and command lookup to make shell sessions predictable.
On this page
Lesson goals
- Distinguish shell variables from exported environment entries.
- Predict quoting, splitting, and wildcard expansion.
- Keep session configuration and secrets under control.
Assignment is shell syntax
A variable assignment such as project=demo has no spaces around the equals sign. project = demo instead asks the shell to run a command named project. Expanding "$project" inserts the value as one argument, including spaces. An unset variable and an empty variable can behave differently in parameter expansion, so defaults should be deliberate. ${name:-fallback} uses a fallback when the value is unset or empty. Curly braces also separate the variable name from following text, as in "${project}_notes".
project='sample notes'
printf '<%s>\n' "$project"
printf '%s\n' "${missing_lab_value:-draft}"
<sample notes>
draft
The first printf receives one argument. The fallback is used when missing_lab_value is unset or empty; choose an unused variable name in a clean lab shell.
Children inherit exported values
Shell variables belong to a shell instance; export places selected values in the environment passed to later child processes. A child receives a copy and cannot rewrite its parent’s environment by changing its own. A temporary assignment before a command limits that value to the command invocation. Environment entries are strings, not a secure secret store. Credentials may be exposed through diagnostics, process inspection, or inherited children. Avoid dumping the entire environment into logs and use the application’s documented credential mechanism when handling real secrets.
LAB_MODE=review bash -c 'printf "%s\n" "$LAB_MODE"'
printf '%s\n' 'parent values are not changed by the child'
review
parent values are not changed by the child
The temporary LAB_MODE assignment is available inside the new Bash only for this invocation. The example passes no real credential.
Quoting controls interpretation
Single quotes preserve literal characters inside them. Double quotes allow parameter and command substitution while preventing ordinary word splitting and pathname expansion of their results. An unquoted variable can first split into words and then expand wildcard patterns, producing surprising argument counts. A variable’s contents are not automatically reparsed as shell syntax; a semicolon inside a quoted value is data. Avoid eval as a shortcut for constructing commands because it introduces another interpretation step. In Bash, arrays are the appropriate tool for preserving a dynamic list of arguments.
PATH and working directory are separate
PATH is a colon-separated search list used for command names without a slash. It does not tell commands where their input files are located. A command containing a slash selects a pathname directly. Putting an untrusted directory, especially the current directory, early in PATH can make an unexpected program win command lookup. Inspect type -a when multiple implementations exist. Aliases mainly help interactive convenience; scripts should not depend on a personal alias. Use documented tool names and explicitly choose an interpreter when the script requires Bash features.
Know which startup file applies
Bash startup behavior depends on whether the shell is interactive and whether it is a login shell. A typical interactive non-login Bash reads ~/.bashrc; login startup follows a different documented sequence. Distribution files can source additional files, so copying a configuration line into several places can duplicate side effects. Keep changes small, open a fresh session to check them, and retain an already working session during troubleshooting. Locale variables influence sorting and messages, while command substitution removes trailing newlines; both details matter when turning an interactive experiment into a repeatable script.
Common errors and fixes
Assignment becomes command not found
- Why it happens
- Spaces were inserted around =.
- How to fix it
- Use name=value and quote the value when necessary.
- Prevent it next time
- Separate shell assignment syntax from ordinary prose.
A child cannot see a variable
- Why it happens
- The shell variable was never exported.
- How to fix it
- Export the selected variable or pass a temporary assignment.
- Prevent it next time
- Document the environment contract of child programs.
A wildcard value expands unexpectedly
- Why it happens
- The expansion was left unquoted.
- How to fix it
- Use double quotes or a Bash array of arguments.
- Prevent it next time
- Treat data as arguments rather than generated shell source.
Check your understanding
1. What is the difference between double-quoted and single-quoted $name?
Show worked solution
Double quotes expand the variable while preserving the result as one argument. Single quotes pass the literal dollar sign and name characters. If name contains a space, the double-quoted form still produces one argument rather than splitting it.
2. A script requires a value only for one child. Choose between a permanent startup-file change and a temporary assignment.
Show worked solution
Use a temporary assignment such as LAB_MODE=review command. It makes the dependency visible beside the invocation and avoids affecting unrelated future programs. If several commands need the value, export it in a deliberately scoped script or subshell.
Key takeaways
- Quote data expansions and pass argument lists without eval.
- Export only what children require and understand startup scope.