Skip to content
Joachim Ansorg edited this page Nov 12, 2021 · 11 revisions

Remove surrounding $() to avoid executing output (or use eval if intentional).

Problematic code:

if $(which epstopdf)
then
  echo "Found epstopdf"
fi

or

make_command() {
  printf 'cat header %q footer > %q\n' "$1" "$2" | tee log
}
$(make_command foo.html output/foo.html)

Correct code:

if which epstopdf
then
  echo "Found epstopdf"
fi

or

make_command() {
  printf 'cat header %q footer > %q\n' "$1" "$2" | tee log
}
eval "$(make_command foo.html output/foo.html)"

Rationale:

ShellCheck has detected that you have a command that just consists of a command substitution. This often happens when you want to run a command (possibly from a variable name), without realizing that $(..) is for capturing and not for executing.

For example, if you have this shell function:

sayhello() { echo "hello world"; }

Then $(sayhello) will:

  1. Run sayhello, capturing "hello world"
  2. Run hello world, resulting in bash: hello: command not found

Meanwhile, just sayhello will:

  1. Run sayhello, outputting "hello world" to screen

Note that this is equally true if the command is in a variable, e.g. x=sayhello; $($x).

If you do have a command that outputs a second command, similar to how ssh-agent outputs export commands to run, then you should do this via eval. This way, quotes, pipes, redirections, semicolons, and other shell constructs will work as expected. Note that this kind of design is best avoided when possible, since correctly escaping all values can be difficult and error prone.

Exceptions:

None.

Related resources:

ShellCheck

Each individual ShellCheck warning has its own wiki page like SC1000. Use GitHub Wiki's "Pages" feature above to find a specific one, or see Checks.

Clone this wiki locally