Linux Expansion
Linux expansions are a powerful feature that allows you to work with your files and commands more efficiently. They are a set of special characters and patterns that automatically expand into useful information. These expansions help you work faster and smarter with your files and commands. Linux expansion (specifically shell expansion) is a process where the shell interprets and replaces certain expressions in a command line before executing it. This allows you to write concise commands that the shell automatically transforms into more complex versions.
Think of it like a magic wand that transforms your commands into something more powerful. Just like how a chef uses different tools to prepare ingredients, Linux gives you special characters and patterns that automatically expand into useful information. These expansions help you work faster and smarter with your files and commands.
The examples below use the course setup. Work in ~/playground/chapter4, where the setup has created sample files and a subdir folder so you can try pathname expansion. Use cd ~/playground/chapter4 before running the pathname and tilde examples. Arithmetic, brace, parameter, and command substitution examples work from any directory; you can run them from ~/playground/chapter4 as well.
Quick Reference
| Expansion Type | What It Does | Common Use |
|---|---|---|
| Pathname | Matches files using patterns | Finding files, listing directories |
| Tilde | Expands to home directories | Navigating to home folders |
| Arithmetic | Performs math operations | Calculations in commands |
| Brace | Creates multiple strings | Making similar files/folders |
| Parameter | Uses variable values | Working with variables |
| Command Substitution | Uses command output | Combining commands |
Order matters: The shell applies expansions in a fixed sequence. Brace expansion runs before pathname (wildcard) expansion, so {...} is never a pathname pattern. Tilde and arithmetic expansion also happen before the shell matches * and ? against filenames.
When to Use Expansions
- When you need to work with multiple files at once
- When you want to save typing time
- When you need to perform calculations
- When you want to create similar files/folders
- When you need to use command output in other commands
Pathname Expansion (Wildcards)
Think of pathname expansion like a search pattern for files. It's like telling your computer "find all files that match this pattern" instead of listing each file individually.
| Pattern | What It Matches | Example |
|---|---|---|
* |
Any number of characters | *.txt matches all text files |
? |
Exactly one character | file?.txt matches file1.txt, fileA.txt |
[abc] |
Any character in the set | [a-c]*.jpg matches a.jpg, b.jpg, c.jpg |
[!abc] |
Any character NOT in the set | [!0-9]*.txt matches files not starting with numbers |
[[:class:]] |
Character class (alnum, alpha, digit, etc.) | [[:digit:]]*.txt matches files starting with numbers |
** |
Recursive matching (bash 4+ / zsh) | **/*.txt matches .txt files in all subdirectories |
Practical Examples
From ~/playground/chapter4, the setup has created file1.txt, file2.txt, file3.txt, fileA.txt, doc1.txt, doc2.txt, alpha.txt, beta.txt, a.jpg, b.jpg, c.jpg, readme.md, notes.md, image1.jpg, image2.png, image3.gif, file1a.txt, file2b.txt, and subdir/other.txt. Try these commands there:
cd ~/playground/chapter4
# List all text files in current directory
ls *.txt
# List files with single character before .txt (file1, file2, file3, fileA)
ls file?.txt
# List all jpg files starting with a, b, or c
ls [a-c]*.jpg
# List all files with numbers in their names
ls *[0-9]*
# List files NOT starting with numbers
ls [!0-9]*
# List files starting with letters
ls [[:alpha:]]*
# List all .txt files in all subdirectories (requires bash 4+ or zsh for **)
ls **/*.txt
# List files matching digit then letter then .txt
ls *[0-9][a-z].txt
Tilde Expansion
Think of the tilde (~) as a shortcut to your home directory. It's like having a "Home" button that takes you to your personal space on the computer.
| Form | What It Expands To | Example |
|---|---|---|
~ |
Your home directory | cd ~ |
~/path |
Home directory plus a path | ls ~/playground/chapter4 |
~username |
Another user's home directory (if permitted) | echo ~student |
Practical Examples
cd ~/playground/chapter4
# Go to your home directory
cd ~
# List files in your playground chapter4 folder (setup directory)
ls ~/playground/chapter4
# Copy a file to your home directory (e.g. copy file1.txt to home)
cp ~/playground/chapter4/file1.txt ~/
# Check another user's home directory (if you have permission)
echo ~username
Arithmetic Expansion
Think of arithmetic expansion like a calculator built into your commands. It lets you do math right in your terminal! In arithmetic expansion in Bash, the dollar sign ($) is used to signify the beginning of an arithmetic expression that needs to be evaluated. When you enclose an expression within $((...)), Bash treats the contents as an arithmetic expression and evaluates it accordingly.
| Form | What It Does | Example |
|---|---|---|
$((expression)) |
Evaluates integer math; result replaces the expression | echo $((5 + 3)) prints 8 |
+ - * / % |
Addition, subtraction, multiplication, division, remainder | echo $((10 % 3)) prints 1 |
( ) |
Groups operations (innermost first) | echo $(( (5 + 3) * 2 )) prints 16 |
| Variables | Variable names work inside $((...)) without $ |
count=5; echo $((count + 1)) prints 6 |
Practical Examples
# Basic math operations (work from any directory)
echo $((5 + 3)) # Addition
echo $((10 - 2)) # Subtraction
echo $((4 * 3)) # Multiplication
echo $((20 / 4)) # Division
# Using variables
count=5
echo $((count + 1))
# Complex calculations
echo $(( (5 + 3) * 2 )) # Parentheses work too!
Brace Expansion
Think of brace expansion like a copy machine that creates multiple versions of similar names. It's perfect for when you need to create several similar files or folders. Brace expansion is not a wildcard: it does not look at existing files; it only generates new words on the command line. That is different from pathname patterns like * and ?, which match filenames on disk.
| Form | What It Generates | Example |
|---|---|---|
{a,b,c} |
Each comma-separated alternative | file{1,2,3}.txt → file1.txt file2.txt file3.txt |
{n..m} |
A numeric range (inclusive) | folder_{1..5} → folder_1 folder_2 ... folder_5 |
{a..z} |
A letter range (inclusive) | {a..c} → a b c |
{nnn..mmm} |
A range with leading zeros preserved | image_{001..003}.png → image_001.png image_002.png image_003.png |
| Nested braces | All combinations (Cartesian product) | {1..2}/{a..c} → 1/a 1/b 1/c 2/a 2/b 2/c |
When combined with globs, brace expansion runs first. For example, ls *.{txt,md} becomes ls *.txt *.md, and then pathname expansion finds matching files for each pattern.
Practical Examples
Run these in ~/playground/chapter4. The setup has already created sample files there (including readme.md, notes.md, and image1.jpg, image2.png, image3.gif) so you can try listing with brace expansion plus globs.
cd ~/playground/chapter4
# Create multiple files (adds file1.txt, file2.txt, file3.txt if not already there)
touch file{1,2,3}.txt
# Create numbered folders
mkdir folder_{1..5}
# Create directories inside of directories (1/a, 1/b, 1/c, 2/a, 2/b, 2/c, 3/a, 3/b, 3/c, 4/a, 4/b, 4/c)
mkdir -p {1..4}/{a..c}
# Create files with leading zeros
touch image_{001..005}.png
# Combine with other text
echo project_{alpha,beta,gamma}_test
# Brace + pathname: list both .txt and .md files (*.{txt,md} becomes *.txt *.md, then globs match)
ls *.{txt,md}
# Brace + pathname: list image files by extension
ls *.{jpg,png,gif}
Parameter Expansion
Think of parameter expansion as a way to use and modify variables in your commands. It's like having a toolbox for working with stored information.
In Bash, when you want to access the value of a variable, you need to use the dollar sign ($) before the variable name. For example, when you use $PATH, you are referencing the value stored in the PATH variable. The dollar sign tells the shell to replace $PATH with the actual value of the PATH variable when the command is executed.
Without the dollar sign, PATH would be treated as a literal string rather than a variable reference. So, to access the value stored in a variable like PATH, you need to use the dollar sign to indicate that you are referring to the variable itself.
Practical Examples
# Show your home directory
echo $HOME
# Show your username
echo $USER
# Show your PATH (first few lines if long)
echo ${PATH}
Command Substitution
Think of command substitution as a way to use the output of one command inside another command. It's like having a conversation where one command's answer becomes part of another command's question.
In Bash, the dollar sign ($) is used to indicate command substitution. Command substitution allows you to run a command and use its output as part of another command or expression.
When you enclose a command within $(), Bash executes the command inside the parentheses and replaces the entire expression with the output of that command. The dollar sign is essential to signify the start of command substitution and to distinguish it from regular text or variables.
Practical Examples
cd ~/playground/chapter4
# Get current date
echo "Today is: $(date)"
# Count files in directory
echo "Files: $(ls | wc -l)"
# Create a file with timestamp
touch "log_$(date +%Y%m%d).txt"
# Use command output in another command (largest file by size)
echo "The largest file is: $(ls -S | head -1)"
Tips for Success
- Start with simple patterns and build up to more complex ones
- Use quotes when you want to prevent expansion
- Test your patterns with
echobefore using them in commands - Remember that different shells might handle expansions slightly differently
- Use
set -xto see how expansions work in real-time
Common Mistakes to Avoid
- Forgetting that spaces in filenames need special handling
- Using the wrong type of quotes (single vs double)
- Not testing patterns before using them with destructive commands
- Forgetting that some expansions need spaces around them
- Mixing up the order of operations in arithmetic expansion
Best Practices
- Use descriptive variable names
- Test expansions with
echofirst - Use quotes when in doubt
- Keep expansions simple and readable
- Comment your code when using complex expansions