Table of Contents
Understanding Variables in Shell Scripts
Variables in shell scripts let you store and reuse values such as text, numbers, filenames, or command output. This chapter focuses on how variables work in typical POSIX shells, with Bash as the main example.
Creating and Assigning Variables
In shell scripts, variable assignment has a strict syntax:
- No spaces around
= - Variable names usually use letters, numbers, and
_, and must not start with a number.
Examples:
name=Alice
greeting="Hello, world"
number=42
file_path=/etc/passwdThese assignments:
- Do not use
=like in many languages with spaces (x = 3is invalid). - By default, create shell variables local to the current shell (not automatically visible to child processes).
Quoting in Assignments
Quotes affect how the shell interprets the value:
- Unquoted: word splitting and globbing (wildcards) may occur.
- Single quotes
'...': preserve the text exactly. - Double quotes
"...": preserve text but still expand variables and some special sequences.
Examples:
text=Hello world # ERROR: word splitting; 'Hello' and 'world' treated separately
text="Hello world" # Correct: single value with a space
pattern=*.txt # Will expand when used, not during assignment
literal_pattern='*.txt' # Exactly the characters *, ., t, x, t
name=Bob
msg='Hi $name' # Literal: $name
echo "$msg" # Output: Hi $name
msg="Hi $name" # Variable expands inside double quotes
echo "$msg" # Output: Hi BobUsing Variables
To use the value stored in a variable, prefix its name with $:
name=Alice
echo $name
echo "User name: $name"To avoid ambiguity between the variable name and following characters, use braces:
user=alice
echo "User is $user01" # Likely empty + '01'
echo "User is ${user}01" # 'alice01'Always quote variables containing user input or paths to avoid unwanted word splitting or globbing:
file="My Document.txt"
rm "$file" # Safe
rm $file # Dangerous: treated as 'My' and 'Document.txt'Variable Naming Conventions
Common conventions:
- Lowercase for your own variables:
file,count,name - Uppercase for “constant-like” or important values:
BACKUP_DIR,LOGFILE - Uppercase often used by the environment/system:
PATH,HOME,USER
Examples:
backup_dir=/backups
LOGFILE=/var/log/my_backup.logTypes of Variables in Shell Scripts
Most shells treat variables as strings by default, but they are used in different ways:
Shell (Local) Variables
These exist only in the current shell session or script.
name=Alice
echo "$name" # Works
bash -c 'echo "$name"' # Empty: not exportedEnvironment Variables (Exported)
Environment variables are visible to child processes. To turn a shell variable into an environment variable, use export:
name=Alice
export name
bash -c 'echo "$name"' # Prints: AliceYou can also assign and export in one step:
export EDITOR=nanoSpecial Parameters and Predefined Variables
Shells provide built-in variables and parameters that have special meaning. Examples (just awareness here; most have their own uses explained elsewhere):
$0– script name$1,$2, … – first, second, etc. positional parameters$#– number of positional parameters$?– exit status of the last command$$– PID of the current shell$!– PID of the last background command$@and$*– all positional parameters
Example (positional parameters):
#!/bin/bash
echo "Script name: $0"
echo "First arg: $1"
echo "Number of args: $#"Reading Input into Variables
Use read to get input from the user:
#!/bin/bash
echo -n "Enter your name: "
read name
echo "Hello, $name!"
Common read options:
-p "prompt"– show prompt without separateecho-s– silent (no echo), useful for passwords-r– raw input (don’t treat backslash as escape)
Example:
#!/bin/bash
read -p "Username: " user
read -s -p "Password: " pass
echo
echo "You entered user '$user' and a hidden password."Command Substitution: Assigning Command Output to Variables
You can store the output of a command in a variable using command substitution.
Preferred modern syntax:
today=$(date)
files=$(ls)Legacy syntax (avoid in new scripts due to nesting/escaping issues):
today=`date`Example:
#!/bin/bash
current_time=$(date +"%Y-%m-%d %H:%M:%S")
user=$(whoami)
echo "Backup started at $current_time by user $user"Always quote the result when using it, unless you intentionally want word splitting:
files=$(ls)
echo "$files" # Prints all filenames in one blockArithmetic with Variables
The shell stores variables as strings, but you can perform integer arithmetic using special syntax.
`$(())` Arithmetic Expansion
This evaluates arithmetic expressions:
a=5
b=3
sum=$((a + b))
prod=$((a * b))
echo "$sum" # 8
echo "$prod" # 15You can also use numbers directly:
x=$((10 + 2 * 3)) # 16
Variables inside $(( )) don’t need $:
count=7
echo $((count + 1)) # 8`let` and `(( ))` for In-Place Arithmetic (Bash)
In Bash, you can do:
count=0
((count++)) # Increment
((count += 5)) # Add 5
echo "$count"Or:
let "count = count + 1"
Prefer $(( )) or (( )) for clarity.
Exporting Variables for Child Processes
To make a variable available to programs that your script runs, use export.
Without export:
#!/bin/bash
MYVAR=hello
env | grep MYVAR # Likely empty, not part of environmentWith export:
#!/bin/bash
export MYVAR=hello
env | grep MYVAR # Shows MYVAR=helloThis is useful for configuring commands that read their settings from environment variables:
#!/bin/bash
export PAGER=less
man bash # 'less' is used as pagerLocal Variables in Functions (Bash)
In Bash, you can limit a variable to a function scope using local:
#!/bin/bash
name="Outer"
show_name() {
local name="Inner"
echo "Inside function: $name"
}
show_name
echo "Outside function: $name"Output:
Inside function: Inner
Outside function: Outer
Without local, the function would overwrite the outer name.
Parameter Expansion Tricks (Defaults and Safety)
Bash and POSIX shells support parameter expansion operators that are especially useful with variables. Common patterns:
${var:-default}– usedefaultifvaris unset or empty; does not changevar${var:=default}– like above, but also setsvartodefaultif it was unset or empty${var:+alt}– usealtonly ifvaris set and non-empty${var:?message}– ifvaris unset/empty, printmessageto stderr and exit the script (non-interactive shells)
Examples:
echo "User: ${USER:-unknown}" # If USER not set, prints 'unknown'
name=${NAME:-Guest} # Uses 'Guest' if NAME not set
logfile=${LOGFILE:=/tmp/app.log} # Ensures LOGFILE has a default
echo "Logging to $logfile"
: "${HOME:?HOME is not set}" # Exit if HOME is missingThe last form is often used at the top of scripts to enforce required variables.
Deleting (Unsetting) Variables
To completely remove a variable:
name=Alice
unset name
echo "$name" # EmptyYou can also unset environment variables:
export API_KEY=123
unset API_KEYPractical Tips for Beginners
- Always use
var=valuewith no spaces around=. - Use
"${var}"(or at least"$var") whenever a variable might contain spaces or special characters. - Prefer
$(command)over backtickscommand. - Use meaningful names:
input_file,backup_dir,user_count, etc. - Use
localinside Bash functions to avoid accidentally overwriting global variables. - Use parameter expansion defaults (
${var:-default}) to keep scripts robust when values are missing.
These basics will be used heavily in conditionals, loops, and functions, which build on the variable concepts introduced here.