Bash Variable Definition and Usage

In the realm of shell scripting, variables are the fundamental building blocks that allow for dynamic and flexible automation. As the most widely used shell in Linux environments, Bash provides a powerful mechanism for variable manipulation. Mastering how to define, reference, and manage these variables is the essential first step toward writing professional, scalable, and error-free scripts.

Basic Syntax and Assignment

Defining a variable in Bash is straightforward, but it is also one of the most common areas where beginners encounter errors. The standard syntax is:

variable_name=value

A critical rule to remember is that you must not include spaces around the equals sign. Bash is sensitive to whitespace; if you add a space, the shell will attempt to interpret the variable name as a command rather than an assignment.

Correct usage:

name="Linux"
age=25
path_dir=/usr/local

Incorrect usage:

name = "Linux"   # Error! Bash will try to execute 'name' as a command

Furthermore, if the value you are assigning contains spaces, you must wrap the value in quotes to ensure the shell treats it as a single string:

greeting="Hello World"

Naming Conventions

To write maintainable code, you should follow established naming conventions. While Bash is somewhat flexible, adhering to these rules prevents conflicts and improves readability:

  • Character Rules: Variable names can only contain letters, numbers, and underscores. Crucially, a name cannot start with a digit.
  • Avoid Reserved Keywords: Do not use Bash reserved words (such as if, for, while, or case) as variable names.
  • Case Sensitivity: By convention, environment variables are typically written in UPPERCASE, while local script variables are written in lowercase. This distinction helps developers quickly identify the scope and purpose of a variable.

Referencing and Expansion

Once a variable is defined, you can access its value by prefixing the name with a dollar sign ($).

name="Bash"
echo $name            # Output: Bash
echo "Hello, $name"   # Output: Hello, Bash

Using Curly Braces for Clarity

While $name works in many cases, it is a best practice to use curly braces ${name}. This explicitly defines the boundaries of the variable name, which is vital when the variable is immediately followed by other characters.

lang="Java"
echo "${lang}Script"   # Output: JavaScript
echo "$langScript"     # Output: (empty, as Bash looks for a variable named 'langScript')

Single vs. Double Quotes

Understanding the difference between single and double quotes is vital for proper variable expansion:

  • Double Quotes ("..."): Allow for parameter expansion. The shell will look inside the quotes and replace the variable name with its actual value.
  • Single Quotes ('...'): Treat everything literally. No expansion occurs; the variable name is treated as plain text.
echo '$name'   # Output: $name
echo "$name"   # Output: Bash

Scope: Local vs. Environment Variables

By default, any variable defined within a script is a local variable. This means it is only accessible within the current shell process and is not passed down to child processes (such as other scripts or commands called by your script).

To make a variable available to child processes, you must use the export command to turn it into an environment variable:

# Method 1: Exporting after definition
MY_VAR="hello"
export MY_VAR

# Method 2: Defining and exporting in one line
export MY_VAR="hello"

Common system environment variables like PATH, HOME, and USER are already exported by the system. You can view all currently active environment variables by using the env or printenv commands.

Managing Variables: Read-only and Unsetting

Bash provides tools to control the lifecycle and mutability of variables.

Making Variables Constant

If you want to ensure a variable's value remains unchanged throughout the script, use the readonly command. This effectively turns the variable into a constant.

readonly PI=3.14
PI=3.1415   # Error: PI: readonly variable

Removing Variables

To delete a variable and free up its name from the current session, use the unset command.

name="test"
unset name
echo $name   # Output: (empty)

Note that a variable marked as readonly cannot be removed using unset.

Command Substitution

One of the most powerful features in Bash is the ability to assign the output of a command directly to a variable. This is known as command substitution. There are two ways to perform this:

  1. The modern syntax: $(command) (Recommended)
  2. The legacy syntax: `command` (Backticks)

While both work, the $(...) syntax is preferred because it is easier to read and allows for easy nesting of commands.

# Using the modern syntax
current_date=$(date +%Y-%m-%d)
file_count=$(ls | wc -l)

echo "Today is $current_date, and there are $file_count files in this directory."

Special Built-in Variables

Bash includes several pre-defined special variables that are indispensable for handling script arguments and system states:

  • $0: The name of the script being executed.
  • $1 through $9: The positional parameters (the first through ninth arguments passed to the script).
  • $#: The total number of arguments passed to the script.
  • $?: The exit status of the last executed command (where 0 indicates success and non-zero indicates an error).
  • $$: The Process ID (PID) of the current shell.

Example usage in a script:

#!/bin/bash
echo "Script Name: $0"
echo "First Argument: $1"
echo "Total Arguments: $#"

Summary of Best Practices

To write robust and professional Bash scripts, keep these core principles in mind:

  1. Always use double quotes when expanding variables to prevent issues with spaces or special characters.
  2. Prefer ${variable} syntax to avoid ambiguity in variable boundaries.
  3. Use $(command) for command substitution instead of backticks.
  4. Be mindful of scope; use export only when child processes truly need access to the data.
  5. Follow naming conventions to distinguish between local logic and system-wide environment settings.