Bash variables are named storage locations in the Bash shell that hold text or numbers, letting you reuse values throughout a script or command session. You assign a value with name=value and read it back with $name or ${name}. This article explains how they work, how to use them correctly, and the pitfalls that trip up newcomers.
Formula
The calculator above works out average pace and speed from a finish time and distance, using the same logic you would apply in a Bash script when dividing two variables. The formulas are:
- Average pace (min/km) = finish time (min) ÷ distance (km)
- Average speed (km/h) = distance (km) ÷ (finish time (min) ÷ 60)
Variables in the equations: t is the finish time in minutes, d is the distance in kilometres, pace is minutes per kilometre, and speed is kilometres per hour. This mirrors how you would store t and d in Bash with t=50 and d=10, then compute pace=$(echo "scale=2; $t / $d" | bc).
Worked Example
Using the defaults from the calculator block: finish time = 50 minutes, distance = 10 km.
- Pace = 50 ÷ 10 = 5.00 min/km
- Speed = 10 ÷ (50 ÷ 60) = 10 ÷ 0.8333 = 12.00 km/h
The calculator shows 5.00 min/km and 12.00 km/h, matching the manual calculation. In Bash, you would write t=50; d=10; pace=$(echo "scale=2; $t / $d" | bc) to get the same 5.00.
What Are Bash Variables, Really?
In the Bash shell, a variable is a name that points to a string of characters. Unlike variables in compiled languages like C or Java, Bash variables have no declared type — everything is text until you use arithmetic expansion. The shell stores the value as a string, and when you reference it with $, the shell substitutes the text in place.
For example, greeting="Hello" stores the literal characters Hello. When you later run echo $greeting, the shell replaces $greeting with Hello and prints it. This substitution happens before the command runs, which is why quoting matters: echo "$greeting" preserves spaces, while echo $greeting splits them.
Variables exist in two scopes: shell variables (local to the current shell) and environment variables (exported to child processes). The distinction is crucial for scripts that call other programs.
Syntax Rules and Naming Conventions
Bash variable names must start with a letter or underscore, followed by letters, digits, or underscores. Hyphens and spaces are not allowed. Valid names include my_var, _count, and var2. Invalid names include my-var and 2var.
When assigning a value, there must be no spaces around the equals sign: name=value works, but name = value is parsed as a command name with arguments. Values containing spaces or special characters must be quoted: message="Hello world" or message='Hello world'.
To read a variable, prefix it with $: echo $name. For clarity and to avoid ambiguity, use braces: echo ${name}. Braces are required when the variable name is followed by other characters, such as ${name}_suffix — otherwise the shell would look for a variable called name_suffix.
Common Operations: Assignment, Expansion, Arithmetic
Beyond simple assignment, Bash offers several ways to manipulate variables:
- Command substitution:
today=$(date)stores the output of thedatecommand intoday. - Arithmetic:
((sum = 3 + 4))orsum=$((3 + 4))performs integer math. Bash cannot handle floating-point arithmetic natively; usebcorawkfor decimals. - Default values:
${var:-default}returnsdefaultifvaris unset or empty, without changingvar.${var:=default}also assigns the default tovar. - String length:
${#var}gives the number of characters invar. - Substring extraction:
${var:offset:length}extracts a portion of the string.
These operations are performed by the shell itself, so they are fast and do not require external commands.
Environment Variables vs. Shell Variables
A shell variable is only visible in the current shell. When you run a script or a command, it inherits the shell’s environment, which is a set of variables that have been exported. To make a variable available to child processes, use the export command:
export PATH="/usr/local/bin:$PATH"
Common environment variables include HOME (your home directory), PATH (where the shell looks for executables), USER (your username), and SHELL (the path to your default shell). These are set by the system or your login profile and are inherited by every command you run.
Without export, a variable set in a script is local to that script. When the script exits, the variable disappears. This is useful for temporary values that should not leak into the parent shell.
Quoting and Word Splitting
The most common source of bugs with Bash variables is forgetting to quote them. When you write echo $var, the shell performs word splitting: it takes the value of var, splits it on spaces, tabs, and newlines, and treats each piece as a separate argument. If var contains hello world, echo $var prints hello world but passes two arguments to echo.
Double quotes ("$var") preserve the value as a single word while still allowing variable expansion and command substitution. Single quotes ('$var') prevent all expansion — the literal string $var is printed. As a rule of thumb, always wrap variable expansions in double quotes unless you specifically want word splitting or globbing.
This becomes critical when variables hold filenames with spaces. A script like rm $file will fail or delete the wrong file if file contains a space. Use rm "$file" instead.
Special Variables and Positional Parameters
Bash provides a set of special variables that you cannot assign to directly:
$0— the name of the script or shell.$1,$2, … — positional parameters (arguments passed to the script).$#— the number of positional parameters.$@— all positional parameters as separate words.$?— the exit status of the last command (0 means success).$$— the process ID of the current shell.
These are read-only in the sense that you cannot do $1=foo, but you can modify positional parameters with the set command. For example, set -- "a" "b" resets $1 to a and $2 to b. Understanding these is essential for writing scripts that accept arguments.
Common Mistakes and How to Avoid Them
Even experienced users make these errors:
- Spaces around
=:name = valuefails. Remove spaces. - Using reserved names: Avoid naming a variable
PATH,HOME, orIFSunless you intend to change system behaviour. OverwritingPATHcan break every command. - Forgetting to export: If a child script cannot see a variable, it was not exported.
- Unquoted expansions: Leads to word splitting and globbing. Quote all expansions unless you need the splitting.
- Using
echofor arbitrary data:echomay interpret backslashes or options. Useprintf '%s\n' "$var"for reliable output.
Another subtle issue is that an unset variable and an empty variable behave differently in some expansions. ${var:-default} treats both as unset, while ${var-default} only uses the default if var is unset, not if it is empty.
Frequently Asked Questions
How do I check if a variable is set in Bash?
Use the -v test: if [[ -v var ]]; then echo "set"; fi. This returns true even if the variable is empty. Alternatively, ${var+x} expands to x if the variable is set, and nothing otherwise.
What is the difference between $var and ${var}?
Functionally they are the same when the variable name is isolated. Braces are needed when the name is followed by other characters, like ${var}_suffix, or when using parameter expansion operators like ${var:-default}. Some style guides recommend always using braces for clarity.
Can a Bash variable hold a number?
Yes, but it is stored as a string. Arithmetic expansion $((...)) treats the string as an integer. For floating-point math, you must use external tools like bc or awk, because Bash itself only supports integers.
How do I make a variable global across all scripts?
Export it in your shell profile (e.g., .bashrc or .profile) with export VAR=value. Then every new shell and every script run from that shell will inherit it. Changes made in a script do not affect the parent shell unless you source the script.
Why does my variable lose its value after a pipe?
Commands in a pipeline run in subshells. A variable assigned inside a subshell is not visible outside it. For example, echo foo | read var; echo $var prints nothing. Use process substitution or shopt -s lastpipe (in interactive Bash) to avoid this.
What is the difference between single and double quotes?
Double quotes allow variable expansion and command substitution, while single quotes suppress all expansion. Use double quotes when you want the variable’s value, and single quotes when you want the literal dollar sign or backtick.
Related
Formula used
in t | Finish time | min | 50 | 0 in d | Distance | km | 10 | 0 | 100000 out pace | Average pace | min/km | t / d | 2 out speed | Average speed | km/h | d / (t / 60) | 2
Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Campus Tech Innovation Hubs: What They Are
- Poco C51 Airtel Prepaid Locked Variant India?
- Jenkins vs GitHub Actions: Which CI/CD Fits Your Team?
- Turn Off Backup Encryption in iTunes?
- Shared VPS Hosting: Is It Better?
- Disk Defrag Pro: What It Does and Whether You Need It