Shell by Example: Variables POSIX + Bash

Variables in shell scripts store values that can be referenced later. Unlike many programming languages, shell variables don’t require type declarations.

To assign a variable, use NAME=value with no spaces around the = sign. This is important!

To use a variable’s value, prefix it with $.

Edit
#!/bin/sh
greeting="Hello"
name="World"

echo "$greeting, $name!"
Output:
Hello, World!

You can also use curly braces for clarity, especially when the variable name could be ambiguous. Without braces, this would try to create a file with the contents “variable” and not “world”.

Edit
#!/bin/sh
variable="world"
echo "${variable}" >hello.txt
cat hello.txt
Output:
world

Variables can hold numbers too, though they are generally treated as strings.

Edit
#!/bin/sh
count=42
echo "The count is $count"
Output:
The count is 42

You can reassign variables at any time, even to different types. In this example, we assign a string to a variable, reassign it to a number, and then reassign it to a string again.

Edit
#!/bin/sh
variable="world"
echo "Hello, $variable!"
variable=42
echo "Hello, $variable!"
variable="world"
echo "Hello, $variable!"
Output:
Hello, world!
Hello, 42!
Hello, world!

Variable names can contain letters, numbers, and underscores. They cannot start with a number.

Edit
#!/bin/sh
variable_1="hello"
variable_2="world"
# 3_variable="would cause an error"
echo "variable_1: $variable_1"
echo "variable_2: $variable_2"
Output:
variable_1: hello
variable_2: world

Unset variables expand to empty strings by default. You can use unset to remove an existing variable, returning it to the undefined state.

Edit
#!/bin/sh
echo "Unset variable: '$undefined_var'"

temp="temporary"
echo "Before unset: $temp"
unset temp
echo "After unset: '$temp'"
Output:
Unset variable: ''
Before unset: temporary
After unset: ''

Bash

Bash provides powerful string manipulation within parameter expansion. These features are not available in POSIX sh.

A few examples of string manipulation:

  • String length with ${#var}:
  • Substring extraction with ${var:start:length}:
  • Remove prefix with ${var#pattern} (shortest) or ${var##pattern} (longest):
  • Remove suffix with ${var%pattern} (shortest) or ${var%%pattern} (longest):
  • Search and replace with ${var/find/replace} (first) or ${var//find/replace} (all):
Edit
#!/bin/bash
message="Hello, World!"
echo "Length: ${#message}"

echo "${message:0:5}"
echo "${message:7}"

path="/home/user/docs/file.txt"
echo "${path##*/}"

echo "${path%/*}"
filename="archive.tar.gz"
echo "${filename%%.*}"

text="hello hello hello"
echo "${text/hello/hi}"
echo "${text//hello/hi}"
Output:
Length: 13
Hello
World!
file.txt
/home/user/docs
archive
hi hello hello
hi hi hi

« Comments | Quoting »