Command substitution lets a Zsh script turn command output into a value before the next command runs. It fits short captures such as line counts, current directory names, generated filenames, or command-derived labels that need to be reused later.
The standard form is $(command). Zsh runs the command in a subshell, captures standard output, removes trailing newline characters, and places the remaining text where the substitution appears.
Quote a command substitution when its output becomes another command's argument. Zsh can still split raw command-substitution output into words, so values containing spaces should be protected before they are passed to commands such as mv, mkdir, or printf.
Related: How to use variables in Zsh
Related: How to use parameter expansion in Zsh
Related: Use command substitution in Bash
Steps to use command substitution in Zsh:
- Create and enter a small workspace for the command-substitution example.
$ mkdir -p use-command-substitution/reports $ cd use-command-substitution $ printf 'alpha\nbeta\ngamma\n' > reports/input.txt
- Create the script that captures command output in Zsh parameters.
- capture-output.zsh
#!/usr/bin/env zsh emulate -L zsh setopt err_exit report=${1:-reports/input.txt} line_count=$(wc -l < "$report") report_name=$(basename "$report") run_dir=$(basename "$PWD") print -r -- "report=$report_name" print -r -- "lines=$line_count" print -r -- "directory=$run_dir"
The redirection in wc -l < "$report" keeps the filename out of the captured output, so line_count receives only the count.
- Check the script syntax.
$ zsh -n capture-output.zsh
No output means Zsh parsed the command substitutions and the rest of the script without a syntax error.
- Run the script and verify the captured values.
$ zsh capture-output.zsh report=input.txt lines=3 directory=use-command-substitution
- Quote command substitutions when the result may contain spaces.
$ report_path="reports/monthly report.txt" $ print -r -- "archive/$(basename "$report_path")" archive/monthly report.txt
The inner quotes protect $report_path before basename runs. The outer quotes protect the substituted filename before print receives it.
- Use the $(...) form when command substitutions are nested or placed inside larger quoted strings.
run_dir=$(basename "$PWD") print -r -- "archive/$(basename "$report_path")"
The older backtick form is harder to read when nested and can break quickly once quoting is added.
- Remove the sample workspace after testing.
$ cd .. $ rm -rf use-command-substitution
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.