-
Notifications
You must be signed in to change notification settings - Fork 1.8k
SC2207
array=( $(mycommand) )
If it outputs multiple lines, each of which should be an element:
# For bash 4.4+, must not be in posix mode, may use temporary files
mapfile -t array < <(mycommand)
# For bash 3.x+, must not be in posix mode, may use temporary files
array=()
while IFS='' read -r line; do array+=("$line"); done < <(mycommand)
# For ksh, and bash 4.2+ with the lastpipe option enabled (may require disabling monitor mode)
array=()
mycommand | while IFS="" read -r line; do array+=("$line"); done
If it outputs a line with multiple words (separated by spaces), other delimiters can be chosen with IFS, each of which should be an element:
# For bash, uses temporary files
IFS=" " read -r -a array <<< "$(mycommand)"
# For bash 4.2+ with the lastpipe option enabled (may require disabling monitor mode)
array=()
mycommand | IFS=" " read -r -a array
# For ksh
IFS=" " read -r -A array <<< "$(mycommand)"
If the output should be a single element:
array=( "$(mycommand)" )
You are doing unquoted command expansion in an array. This will invoke the shell's sloppy word splitting and glob expansion.
Instead, prefer explicitly splitting (or not splitting):
- If you want to split the output into lines or words, use
mapfile
,read -ra
and/orwhile
loops as appropriate. - If the command output should become a single array element, quote it.
This prevents the shell from doing unwanted splitting and glob expansion, and therefore avoiding problems with output containing spaces or special characters.
If you have already taken care (through setting IFS and set -f
) to have word splitting work the way you intend, you can ignore this warning.
Another exception is the wish for error handling: array=( $(mycommand) ) || die-with-error
works the way it looks while a similar mapfile
construct like mapfile -t array < <(mycommand)
doesn't fail and you will have to write more code for error handling.