0

I have a script which I checked with shellcheck. To one command I pass arguments/flags as a string and shellcheck complained about it, i.e. I do following

options="-j 5 -B"
make $options file

instead, they [1] suggest to do the following without explicitly mentioning why it is better

options=(-j 5 -B) # ksh: set -A options -- -j 5 -B
make "${options[@]}" file

Why is the latter example better than former?

[1] https://github.com/koalaman/shellcheck/wiki/SC2086

leopik
  • 123

1 Answers1

2

In the simple case, it does not matter.

If some of the options need quoting, consider:

options=(-j 5 "Hello, World" -B)
make "${options[@]}" file

The four elements are quoted properly in the array initialisation, and the array substitution leaves them correctly as distinct words.

The one-step substitution can't be fixed with partial quotes (even with single quotes around the string). It comes out as either one option, or five: never four.

paul $ options="-j 5 'Hello, World' -B"
paul $ declare -p options
declare -- options="-j 5 'Hello, World' -B"
paul $ printf '%s\n' $options
-j
5
'Hello,
World'
-B
$ printf '%s\n' "$options"
-j 5 'Hello, World' -B
$ 

Compared to:

paul $ options=(-j 5 "Hello, World" -B)
paul $ declare -p options
declare -a options='([0]="-j" [1]="5" [2]="Hello, World" [3]="-B")'
paul $ printf '%s\n' "${options[@]}"
-j
5
Hello, World
-B
paul $ 
ilkkachu
  • 138,973
Paul_Pedant
  • 8,679