On Sun, 17 Mar 2024, Greg Wooledge wrote:

On Sun, Mar 17, 2024 at 09:25:10AM +0000, Tim Woodall wrote:
In almost all other cases, the space separated items cannot, even in
theory, contain a rogue space, so suppressing the warning is fine

Famous Last Words™.

As one example, it calls out to an external program that builds a cache
in a temporary dir and it can be told to keep that temporary dir for
future runs.

$ cat test
#!/bin/bash

do_work()
{
  local f=0
  while [[ $1 =~ ^-- ]]; do
    [[ $1 = "--fast" ]] && f=1
    shift
  done
  echo -n "first file arg = '$1'"
  [[ ${f} -eq 1 ]] && echo -n " running with --fast"
  echo
}

loopitems=(
  aitem1
  aitem2
  bitem1
  bitem2
)

declare -A fast

echo "No quoting"
for i in "${loopitems[@]}"; do
  do_work ${fast[${i:0:1}]} --option1 --option2 "${i}"
  fast[${i:0:1}]=--fast
done

echo
echo "Quoting"
unset fast
declare -A fast
for i in "${loopitems[@]}"; do
  do_work "${fast[${i:0:1}]}" --option1 --option2 "${i}"
  fast[${i:0:1}]=--fast
done



$ shellcheck test

In test line 26:
  do_work ${fast[${i:0:1}]} --option1 --option2 "${i}"
          ^---------------^ SC2086: Double quote to prevent globbing and word 
splitting.

Did you mean:
  do_work "${fast[${i:0:1}]}" --option1 --option2 "${i}"


$ ./test
No quoting
first file arg = 'aitem1'
first file arg = 'aitem2' running with --fast
first file arg = 'bitem1'
first file arg = 'bitem2' running with --fast

Quoting
first file arg = ''
first file arg = 'aitem2' running with --fast
first file arg = ''
first file arg = 'bitem2' running with --fast


because fast is an array I can't use the trick that "${x[@]}"
expands to nothing at all when fast is a list because you cannot have an
array of lists.

I could, instead, use something like (I haven't tested these exactly
lines so tweaks are possibly needed)

declare -a "fast_${i:0:1}=( --fast )"

and
declare -n "v=fast_${i:0:1}"
do_work "${v[@]}" ...

Which is what I've now done in the one place where filenames were
involved.

Reply via email to