dotlinux blog

Understanding and Writing ‘Linux Variables’ in Shell Scripting

Shell scripting is a cornerstone of Linux system administration and automation, enabling users to execute complex tasks, manage systems, and streamline workflows. At the core of shell scripting are variables—dynamic entities that store data (e.g., strings, numbers, file paths) and make scripts flexible, reusable, and adaptable. Whether you’re automating backups, configuring servers, or building utilities, mastering shell variables is essential for writing robust and efficient scripts.

In this guide, we’ll explore the fundamentals of Linux variables in shell scripting, including their types, declaration, manipulation, scope, and practical applications. By the end, you’ll be equipped to leverage variables effectively in your own scripts.

2026-05

Table of Contents#

  1. What are Shell Variables?
  2. Declaring and Initializing Variables
  3. Variable Types in Shell Scripting
  4. Accessing Variables
  5. Modifying Variables
  6. Variable Scope
  7. Special Variable Operations (Parameter Expansion)
  8. Environment Variables: Persistence and Scope
  9. Practical Examples of Shell Scripts with Variables
  10. Common Pitfalls and Best Practices
  11. Advanced Topics (Arrays)
  12. Conclusion
  13. References

1. What are Shell Variables?#

A shell variable is a named entity that stores data (e.g., text, numbers, or file paths). Variables enable scripts to:

  • Store temporary data (e.g., user input, command outputs).
  • Make scripts dynamic (e.g., reuse values across commands).
  • Configure behavior (e.g., enable debug mode with a flag).

Shell variables are loosely typed—the shell infers the type (string, number, etc.) based on context (e.g., arithmetic operations vs. string concatenation).

2. Declaring and Initializing Variables#

Syntax#

To declare (and initialize) a variable, use:

variable_name=value
  • No spaces around = (critical: variable_name = value throws an error).
  • Variable names:
    • Contain letters (A-Z, a-z), numbers (0-9), or underscores (_).
    • Start with a letter or underscore (not a number).
    • Are case-sensitive (e.g., MYVARmyvar).

Examples#

# String (quotes optional for simple strings, required for spaces)
NAME="John Doe"
 
# Number
AGE=30
 
# File path
LOG_FILE="/var/log/app.log"
 
# Empty variable
EMPTY_VAR=

Quoting Variables#

For strings with spaces or special characters, use quotes:

# Correct (preserves spaces)
MESSAGE="Hello, how are you?"
 
# Incorrect (shell tries to run "how" as a command)
MESSAGE=Hello, how are you?

3. Variable Types in Shell Scripting#

Shell variables fall into categories with distinct behaviors:

a. Local Variables#

  • Exist only in the current shell session/script (not inherited by child processes).
  • Used for temporary data (e.g., intermediate results in a script).

Example:

#!/bin/bash
LOCAL_VAR="I am local"
echo $LOCAL_VAR  # Visible in this script

b. Environment Variables#

  • Inherited by child processes (e.g., scripts, commands run from the script).
  • Configure system/application behavior (e.g., PATH, HOME, USER).

To export a local variable as an environment variable:

MY_VAR="Hello"
export MY_VAR  # Now inherited by child processes

c. Shell Variables#

  • Built-in variables defined by the shell (e.g., BASH_VERSION, SHELL).
  • Some are read-only (e.g., $SHELL cannot be modified).

View all shell variables with set:

set  # Lists all variables (local, environment, shell)

d. Positional Parameters#

  • Store command-line arguments passed to a script/function (e.g., $1, $2, ..., $9).
  • $*/$@: All positional parameters (see Special Variables).

Example (script: greet.sh):

#!/bin/bash
echo "Hello, $1! You are $2 years old."

Run:

./greet.sh Alice 25  # Output: Hello, Alice! You are 25 years old.

e. Special Variables#

Predefined variables with unique roles:

  • $0: Script name (e.g., greet.sh).
  • $?: Exit status of the last command (0 = success, non-0 = error).
  • $$: Process ID (PID) of the current shell.
  • $!: PID of the last background job.
  • $*/$@: All positional parameters (e.g., "$@" preserves spaces in arguments).

Example:

#!/bin/bash
echo "Script name: $0"
echo "PID: $$"
 
sleep 5 &  # Run in background
echo "Background job PID: $!"
 
exit 0
echo "Exit status: $?"  # Not executed (after `exit`)

4. Accessing Variables#

To use (expand) a variable, prefix its name with $:

Basic Expansion: $variable_name#

NAME="Alice"
echo "Hello, $NAME!"  # Output: Hello, Alice!

Curly Brace Expansion: ${variable_name}#

  • Disambiguate variable names (e.g., when appending text).
  • Access array elements (advanced).

Example 1: Disambiguation

NAME="Alice"
echo "Hello, ${NAME}s!"  # Output: Hello, Alices! (vs. $NAMEs → error)

Example 2: Default Values (advanced)

echo "Value: ${MYVAR:-default}"  # Use "default" if MYVAR is unset/empty

5. Modifying Variables#

Reassignment#

Change a variable’s value:

COUNT=10
COUNT=20  # Reassign
echo $COUNT  # Output: 20

Arithmetic Operations#

Use $(( ... )) for integer arithmetic:

NUM1=5
NUM2=3
SUM=$(( NUM1 + NUM2 ))
echo "Sum: $SUM"  # Output: 8

String Operations#

Concatenation#

FIRST="Hello"
LAST="World"
GREETING="${FIRST} ${LAST}"
echo $GREETING  # Output: Hello World

Substring Extraction#

Syntax: ${variable:start:length} (index starts at 0):

TEXT="Hello, World"
SUB="${TEXT:7:5}"  # Extract "World" (index 7, length 5)
echo $SUB          # Output: World

String Length#

Syntax: ${#variable}:

TEXT="Hello"
LENGTH=${#TEXT}  # 5
echo $LENGTH     # Output: 5

6. Variable Scope#

Local vs. Global in Functions#

  • Global variables: Visible everywhere in the script (including functions).
  • Local variables: Use local to limit scope to a function (prevents interference).

Example:

#!/bin/bash
GLOBAL="I am global"
 
my_function() {
  local LOCAL="I am local"  # Only visible in this function
  echo "Inside: $GLOBAL, $LOCAL"
  GLOBAL="Modified"  # Modifies the global variable
}
 
my_function
echo "Outside: $GLOBAL, $LOCAL"  # $LOCAL is undefined here

Output:

Inside: I am global, I am local
Outside: Modified, 

Exporting to Child Processes#

By default, local variables are not inherited by child processes. Use export to share them:

Parent script (parent.sh):

#!/bin/bash
export MY_VAR="Hello from parent"
./child.sh

Child script (child.sh):

#!/bin/bash
echo "Child sees: $MY_VAR"  # Output: Child sees: Hello from parent

7. Special Variable Operations (Parameter Expansion)#

Parameter expansion manipulates variable values. Common use cases:

1. Default Value (if unset/empty)#

  • ${var:-default}: Use default (does not set var).
  • ${var:=default}: Use default (and set var to default).

Example:

echo "${VAR:-fallback}"  # Fallback if VAR is unset
echo "${VAR:=fallback}"  # Fallback and set VAR to fallback

2. Alternate Value (if set/non-empty)#

  • ${var:+alternate}: Use alternate only if var is set/non-empty.

Example:

VAR="hello"
echo "${VAR:+world}"  # Output: world (VAR is set)

3. Pattern Matching (Remove Prefix/Suffix)#

  • ${var#pattern}: Shortest prefix match.
  • ${var##pattern}: Longest prefix match.
  • ${var%pattern}: Shortest suffix match.
  • ${var%%pattern}: Longest suffix match.

Example (Prefix):

PATH="/usr/bin:/usr/local/bin:/bin"
echo "${PATH#*/}"    # Output: usr/bin:/usr/local/bin:/bin
echo "${PATH##*/}"   # Output: bin

8. Environment Variables: Persistence and Scope#

Session-specific Variables#

Set in the current shell session (lost when the session ends):

export MY_SESSION_VAR="temporary"

Persistent Variables#

To make variables persistent (across sessions):

For a Specific User:#

Edit ~/.bashrc (Bash) or ~/.zshrc (Zsh):

export MY_USER_VAR="permanent"

Reload: source ~/.bashrc

For All Users:#

Edit /etc/environment (no export needed):

MY_SYSTEM_VAR="permanent for all"

Or edit /etc/profile (runs for all users on login):

export MY_SYSTEM_VAR="permanent for all"

9. Practical Examples of Shell Scripts with Variables#

Example: Simple Calculator#

#!/bin/bash
echo "Enter first number:"
read NUM1
echo "Enter second number:"
read NUM2
 
SUM=$(( NUM1 + NUM2 ))
DIFF=$(( NUM1 - NUM2 ))
PROD=$(( NUM1 * NUM2 ))
QUOT=$(( NUM1 / NUM2 ))
 
echo "Sum: $SUM"
echo "Difference: $DIFF"
echo "Product: $PROD"
echo "Quotient: $QUOT"

Run:

./calculator.sh  # Input 10 and 5 → Sum: 15, etc.

Example: Backup Script#

#!/bin/bash
SOURCE_DIR="/home/user/docs"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
BACKUP_FILE="backup_${DATE}.tar.gz"
 
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/$BACKUP_FILE $SOURCE_DIR
 
echo "Backup created: $BACKUP_DIR/$BACKUP_FILE"

This script uses variables to:

  • Define paths.
  • Generate a timestamped filename.
  • Log results.

10. Common Pitfalls and Best Practices#

Pitfalls to Avoid#

  1. Spaces around =:
    Wrong: VAR = "value" (shell runs VAR as a command).
    Correct: VAR="value".

  2. Unquoted variables with spaces:
    Wrong: echo $MESSAGE (may split into multiple arguments).
    Correct: echo "$MESSAGE".

  3. Overwriting built-in variables:
    Avoid overwriting PATH, HOME, or PS1.

Best Practices#

  1. Descriptive names: Use LOG_FILE instead of lf.
  2. Quote variables with spaces: echo "$USER_INPUT".
  3. readonly for constants:
    readonly VERSION="1.0"  # Prevents accidental changes

11. Advanced Topics (Arrays)#

Declaring Arrays#

# Method 1: Space-separated values
FRUITS=("apple" "banana" "cherry")
 
# Method 2: Indexed assignment
FRUITS[0]="apple"
FRUITS[1]="banana"

Accessing Array Elements#

echo "${FRUITS[0]}"   # apple
echo "${FRUITS[@]}"   # all elements: apple banana cherry
echo "${#FRUITS[@]}"  # length: 3

Looping Through Arrays#

for fruit in "${FRUITS[@]}"; do
  echo "I like $fruit"
done

Conclusion#

Shell variables are the backbone of dynamic and reusable shell scripts. By mastering their types, scope, and manipulation, you can automate complex tasks, configure systems, and build efficient workflows. Use the examples and best practices here to write cleaner, more robust scripts.

References#

  1. Bash Manual: Official documentation for Bash variables:
    https://www.gnu.org/software/bash/manual/

  2. Linux Documentation Project (LDP): Guides on shell scripting:
    https://tldp.org/

  3. Book: Learning the bash Shell by Cameron Newham and Bill Rosenblatt:
    A comprehensive guide to Bash scripting.

  4. GNU Coreutils Manual: For commands like export, readonly, and set:
    https://www.gnu.org/software/coreutils/manual/