Assume a function that runs a command in another directory:
sub() {
cd subdirectory
eval "$@" || exit
}
I would like to be able to invoke this function with parameters that are expanded inside the subdirectory, e.g. sub ls '$(basename $(pwd))'
However, as the function is defined above, it does not pass shellcheck:
^-- SC2294 (warning): eval negates the benefit of arrays. Drop eval to preserve whitespace/symbols (or eval as string).
Obviously, if I remove the eval, then the parameter is not expanded and if I remove the quotes as well, then the parameter is expanded in the current directory. Which is not what I want.
I understand there are some suggestions in shellcheck's wiki, but I don't know how to make them work.
Is it possible to use eval correctly in this scenario -- without the downsides described in SC2294 -- or do I need to ignore this rule?
CodePudding user response:
Use eval "$*"
instead of eval "$@"
. That will have exactly the same effect (assuming that IFS
has its default value) and Shellcheck is happy with it. See Accessing bash command line args $@ vs $* for details of $@
versus $*
(quoted and unquoted).
Use of eval
is, justifiably, generally discouraged. See Why should eval be avoided in Bash, and what should I use instead?. Sometimes there's no better option though.
CodePudding user response:
... Drop eval ...
So drop it.
sub() {
cd subdirectory
"$@" || exit
# I would do:
if ! "$@"; then
exit
fi
}