SC2046: Unquoted Command Substitution

Avoid word splitting bugs by quoting $() command substitutions. Learn when and how to properly quote command output in bash scripts.

Quoting

Detailed Explanation

Quoting Command Substitutions

Command substitutions with $() or backticks are subject to the same word splitting and globbing rules as regular variable expansion. Unquoted command substitutions can produce unexpected results.

The Problem

# BAD: unquoted command substitution
current_dir=$(pwd)
cd $current_dir  # Breaks if path contains spaces

# GOOD: quoted command substitution
current_dir=$(pwd)
cd "$current_dir"

Real-World Example

# BAD: Breaks on filenames with spaces
for file in $(find . -name "*.log"); do
  echo "Processing $file"
done

# GOOD: Use find -exec or while read
find . -name "*.log" -exec echo "Processing {}" \;

# Or use process substitution with read
while IFS= read -r file; do
  echo "Processing $file"
done < <(find . -name "*.log")

Nested Command Substitutions

One advantage of $() over backticks is clean nesting:

# Clean nesting with $()
echo "Kernel: $(uname -r) on $(hostname)"

# Messy with backticks (requires escaping)
echo "Kernel: \`uname -r\` on \`hostname\`"

When to Leave Unquoted

Intentional splitting of command output into array elements:

# Intentional: populate array from command output
files=($(ls *.txt))  # Note: still problematic with special chars

Even here, a while-read loop is safer for handling arbitrary filenames.

Use Case

Build scripts, deployment pipelines, and automation tools that capture command output and use it in subsequent commands. Particularly important in scripts that process file paths returned by find, ls, or other commands.

Try It — Shell Script Linter

Open full tool