-
Notifications
You must be signed in to change notification settings - Fork 1.8k
SC2145
printf "Error: %s\n" "Bad parameters: $@"
printf "Error: %s\n" "Bad parameters: $*"
The behavior when concatenating a string and array is rarely intended. The preceeding string is prefixed to the first array element, while the succeeding string is appended to the last one. The middle array elements are unaffected.
E.g., with the parameters foo
,bar
,baz
, "--flag=$@"
is equivalent to the three arguments "--flag=foo" "bar" "baz"
.
If the intention is to concatenate all the array elements into one argument, use $*
. This concatenates based on IFS
.
If the intention is to provide each array element as a separate argument, put the array expansion in its own argument.
Concatenating a string with an array can be used to make a command line interface with subcommands.
To implement the subcommand interface, first pick a prefix like subcommand_
below for the names of the functions that implement the subcommands. Then protect the parsing of the subcommands by listing them as patterns of a case statement. In the body of the case statement, a concatenation of the prefix with "$@"
will invoke the subcommand function and pass the rest of the parameters to the function.
For example:
subcommand_foo() {
echo "In foo"
echo "\$1 == $1 == aaa"
echo "\$2 == $2 == bbb"
}
subcommand_bar() {
echo "In bar"
}
subcommand_baz() {
echo "In baz"
}
main() {
case "$1" in
foo | bar | baz )
subcommand_"$@"
;;
* )
printf "Error: %s\n" "Unrecognized command"
;;
esac
}
main foo aaa bbb
main bar
In the above example, inside the main
function the value of "$@"
is ( foo aaa bbb )
. The value of subcommand_"$@"
after expansion is ( subcommand_foo aaa bbb )
, which the shell interprets as a call to subcommand_foo
with parameters aaa
and bbb
.