Przejdลบ do treล›ci

๐Ÿ” Advanced Expansions

Shell expansions transform text and compute values inline โ€” mastering them enables concise, powerful scripts.

๐Ÿงญ Expansion Types Overview

Shells perform several types of expansions in order:

  1. Brace Expansion โ€” {a,b}{1,2}
  2. Tilde Expansion โ€” ~, ~/Documents
  3. Parameter Expansion โ€” $var, ${var}, ${var:-default}
  4. Command Substitution โ€” $(command), `command`
  5. Arithmetic Expansion โ€” $((expression))
  6. Word Splitting โ€” Splitting on $IFS
  7. Filename Expansion โ€” Globbing *.txt

๐Ÿงช Parameter Expansion Deep Dive

Default Value Substitution

1
2
3
4
5
# If var is unset or empty, use default
echo "${var:-default}"        # Use default
: "${EDITOR:=nano}"           # Set if unset
echo "${var:?Error message}"  # Exit if unset
echo "${var:+alternative}"    # Use alternative if set

String Manipulation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
filename="/home/user/document.pdf"

# Remove shortest match from beginning
echo "${filename#/*/}"        # user/document.pdf

# Remove longest match from beginning
echo "${filename##/*/}"       # document.pdf

# Remove shortest match from end
echo "${filename%.*}"         # /home/user/document

# Remove longest match from end
echo "${filename%%.*}"        # /home/user/document

# Replace first occurrence
echo "${filename/\/home/\/opt}"  # /opt/user/document.pdf

# Replace all occurrences
echo "${filename//\//_}"      # _home_user_document.pdf

Substring Extraction

1
2
3
4
5
6
7
8
9
string="Hello World"

# Extract substring
echo "${string:0:5}"          # Hello
echo "${string:6}"            # World
echo "${string: -5}"          # World (note space before -)

# Length
echo "${#string}"             # 11

๐Ÿง  Pattern-Based Expansions

Case Conversion (Bash 4.0+)

1
2
3
4
5
6
str="Hello World"

echo "${str^^}"               # HELLO WORLD
echo "${str,,}"               # hello world
echo "${str^}"                # Hello World (first char)
echo "${str,}"                # hello World (first char)

Indirect Variable References

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
varname="USER"
value="${!varname}"           # Equivalent to $USER

# Dynamic configuration access
DB_HOST="localhost"
DB_PORT="5432"

for var in DB_HOST DB_PORT; do
    echo "${var}: ${!var}"
done

โš ๏ธ Not POSIX โ€” avoid in portable scripts.


๐Ÿงช Command Substitution

Modern Syntax

1
2
3
4
5
6
# Preferred method
today=$(date +%Y-%m-%d)
files=$(find . -name "*.log")

# Nested substitution
result=$(grep -l "$(hostname)" configs/*.conf)

Legacy Syntax (Avoid)

1
2
# Old style - harder to nest
today=`date +%Y-%m-%d`

Handling Special Characters

1
2
3
4
5
6
7
8
# Command substitution removes trailing newlines
output=$(printf "line1\nline2\n")
echo "[$output]"  # [line1
                  # line2]

# Preserve all output
output=$(command; echo x)
output=${output%x}

๐Ÿง  Arithmetic Expansion

Basic Arithmetic

1
2
3
4
5
6
7
# Simple calculations
sum=$((2 + 3 * 4))            # 14
index=$((index + 1))

# Bit operations
mask=$((0xFF & 0x0F))         # 15
shifted=$((8 << 2))           # 32

Conditional Expressions

1
2
3
4
5
# Ternary-like operator
result=$(( a > b ? a : b ))

# Boolean logic
enabled=$(( flag == 1 ? 1 : 0 ))

Array Indexing (Bash)

1
2
3
4
arr=(apple banana cherry)
index=1
echo "${arr[$index]}"         # banana
echo "${arr[$((index + 1))]}" # cherry

๐Ÿงช Brace Expansion

Sequence Generation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Numeric ranges
echo file{1..5}.txt           # file1.txt file2.txt ... file5.txt

# Zero-padded sequences
echo file{01..05}.txt         # file01.txt file02.txt ... file05.txt

# Reverse sequences
echo {5..1}                   # 5 4 3 2 1

# Character ranges
echo {a..e}                   # a b c d e

Cartesian Products

1
2
3
4
5
# Generate combinations
echo {a,b}{1,2}               # a1 a2 b1 b2

# Complex structures
mkdir -p project/{src,tests,docs}/{main,util,shared}

๐Ÿง  Word Splitting and IFS

Default Behavior

1
2
3
4
5
# Default IFS: space, tab, newline
words="one two three"
for word in $words; do
    echo "Word: [$word]"
done

Custom IFS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Split on comma
data="apple,banana,cherry"
IFS=',' read -ra fruits <<< "$data"
for fruit in "${fruits[@]}"; do
    echo "Fruit: [$fruit]"
done

# Temporary IFS change
old_ifs="$IFS"
IFS=':'
read user pass uid gid rest < /etc/passwd
IFS="$old_ifs"

Preventing Splitting

1
2
3
4
# Quote to prevent splitting
for item in "$words"; do
    echo "Item: [$item]"      # [one two three]
done

๐Ÿงช Filename Expansion (Globbing)

Basic Patterns

1
2
3
4
# Wildcards
ls *.txt                      # All .txt files
ls file?.log                  # file1.log, fileA.log
ls [a-c]*.sh                  # Files starting with a,b,c

Extended Globs (Bash)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
shopt -s extglob

# Match anything except pattern
ls !(temp).txt                # All .txt except temp.txt

# Match one of patterns
ls @(file1|file2).txt         # file1.txt or file2.txt

# Match zero or one occurrence
ls file?(.bak).txt            # file.txt or file.bak.txt

Recursive Globbing (Bash 4.3+)

1
2
shopt -s globstar
ls **/*.txt                   # All .txt files recursively

๐Ÿง  Expansion Order Examples

Complex Nesting

1
2
3
4
5
6
# Expansion order demonstration
files=(*.txt)
echo "First file: ${files[0]##*/}"  # Basename of first .txt file

# Nested parameter expansion
config="${CONFIG_FILE:-${HOME}/.config/app.conf}"

Timing Considerations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Expensive expansion - evaluated every time
for i in {1..1000}; do
    echo "Date: $(date)"        # Slow - 1000 date calls
done

# Better approach - cache result
current_date=$(date)
for i in {1..1000}; do
    echo "Date: $current_date"  # Fast - 1 call
done

๐Ÿงพ Portability Notes

Feature POSIX Bash Zsh
${var:-default} โœ… โœ… โœ…
${var:=default} โœ… โœ… โœ…
${var:?error} โœ… โœ… โœ…
${var:+alt} โœ… โœ… โœ…
${var^^} (case) โŒ โœ… โœ…
${!var} (indirect) โŒ โœ… โœ…
$((arithmetic)) โœ… โœ… โœ…
{1..5} (brace) โŒ โœ… โœ…
Extended globs โŒ โœ… โœ…

๐Ÿงพ Summary

  • Master parameter expansions for robust default handling
  • Use brace expansion for generating sequences and structures
  • Prefer $() over backticks for command substitution
  • Leverage arithmetic expansion for calculations
  • Control word splitting with careful quoting and IFS
  • Understand expansion order to predict behavior
  • Test portability with multiple shell implementations

๐Ÿ‘‰ Continue to: Error Semantics