Pattern: Use of $()
to execute output
Issue: -
This rule checks if command just consists of a command substitution.
This is typically done in order to try to get the shell to execute a command, because $(..)
does indeed execute commands. However, it's also replaced by the output of that command.
When you run echo "The date is $(date +%F)"
, bash evaluates the $(..)
. The command then becomes echo "The date is 2015-04-29"
, which writes out the string The date is 2015-04-29
The problem is when you use $(date +%F)
alone as a command. Bash evaluates the $(..)
, and the command then becomes 2015-04-29
. There is no command called 2015-04-29
, so you get bash: 2015-04-29: command not found
.
Sometimes this results in this confounding command not found
messages. Other times you get even stranger issues, like the example problematic code which always evaluates to false.
The solution is simply to remove the surrounding $()
. This will execute the command instead of the command's output.
Example of incorrect code:
if $(which epstopdf)
then
echo "Found epstopdf"
fi
Example of correct code:
if which epstopdf
then
echo "Found epstopdf"
fi
If you really want to execute the output of a command rather than the command itself, you can ignore this message or assign the output to a new variable first:
readonly command_to_execute="$(print_the_command)"
"$command_to_execute"