1

Can you tell me, why I have to # shellcheck disable=SC2030 in the following script?

get_names_and_hosts(){

  unset LOCAL_HOSTS
  declare -a LOCAL_HOSTS

  unset LOCAL_NAMES
  declare -a LOCAL_NAMES

  multipass list --format json | jq -r '.list[] | [ .name, .ipv4[0] ] | @tsv' |
  while IFS=$'\t' read -r name ipaddress; do
      # shellcheck disable=SC2030
      LOCAL_NAMES+=("$name")
      # shellcheck disable=SC2030
      LOCAL_HOSTS+=($ipaddress)
  done

  # shellcheck disable=SC2031
  reply=("${LOCAL_NAMES[@]}" "${LOCAL_HOSTS[@]}")
  echo "${reply[@]}"
}

declare as declare -gx gives the same warning?

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
Chris G.
  • 143
  • 5

1 Answers1

2

Because the previous line ends with |, the while ... do ... done loop is part of the pipeline: you are piping into a loop.

Because of this, the loop may be executed in a subshell, and so any changes to the variables LOCAL_NAMES and LOCAL_HOSTS might be lost depending on which shell you are actually using to run this script: it will work with ksh, zsh and also with bash if you have bash's lastpipe option set.

With other shells, or with bash's factory-default settings, it will fail.

Was the explanation on https://www.shellcheck.net/wiki/SC2031 not clear for you?

telcoM
  • 87,318
  • 3
  • 112
  • 232