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.

Steps to use command substitution in Zsh:

  1. 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
  2. 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.

  3. 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.

  4. Run the script and verify the captured values.
    $ zsh capture-output.zsh
    report=input.txt
    lines=3
    directory=use-command-substitution
  5. 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.

  6. 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.

  7. Remove the sample workspace after testing.
    $ cd ..
    $ rm -rf use-command-substitution