Updated SC2124 (markdown)

Vidar Holen
2020-11-19 13:26:41 -08:00
parent 2a43cfc864
commit a0e64db161

@@ -1,13 +1,9 @@
## Assigning an array to a string! Assign as array, or use * instead of @ to concatenate. ## Assigning an array to a string! Assign as array, or use * instead of @ to concatenate.
### Danger!
> Changing this parameter can be dangerous. Its behavior is influenced by the value of `IFS`. In certain situations (like feeding strings into commands) this can result in unexpected results from a seemingly aesthetic-only change.
[[More info]](https://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables)
### Problematic code: ### Problematic code:
```sh ```sh
# Want to store multiple elements in var
var=$@ var=$@
for i in $var; do ..; done for i in $var; do ..; done
``` ```
@@ -16,6 +12,7 @@ or
```sh ```sh
set -- Hello World set -- Hello World
# Want to concatenate multiple elements into a single string
msg=$@ msg=$@
echo "You said $msg" echo "You said $msg"
``` ```
@@ -23,14 +20,22 @@ echo "You said $msg"
### Correct code: ### Correct code:
```sh ```sh
# Bash: use an array variable
var=( "$@" ) var=( "$@" )
for i in "${var[@]}"; do ..; done for i in "${var[@]}"; do ..; done
# POSIX sh: without array support, one possible workaround
# is to store elements concatenated with a delimiter (here linefeed/newline)
var=$(printf '%s\n' "$@")
printf '%s\n' "$var" | while IFS='' read -r line; do ..; done
``` ```
or or
```sh ```sh
#!/bin/sh
set -- Hello World set -- Hello World
# Explicitly concatenates all the array elements into a single string
msg=$* msg=$*
echo "You said $msg" echo "You said $msg"
``` ```
@@ -41,7 +46,9 @@ Arrays and `$@` can contain multiple elements. Simple variables contain only one
Since doing this usually indicates a bug, ShellCheck warns and asks you to be explicit about what you want. Since doing this usually indicates a bug, ShellCheck warns and asks you to be explicit about what you want.
If you want to assign N elements as N elements, use an array, e.g. `myArray=( "$@" )`. If you want to assign N elements as N elements in Bash or Ksh, use an array, e.g. `myArray=( "$@" )`.
Dash and POSIX sh do not support arrays. In this case, either concatenate the values with some delimiter that you can split on later (the example uses linefeeds and splits them back up with a `while read` loop), or keep the values as positional parameters without putting them in an array.
If you want to assign N elements as 1 element by concatenating them, use `*` instead of `@`, e.g. `myVar=${myArray[*]}` (this separates elements with the first character of `IFS`, usually space). If you want to assign N elements as 1 element by concatenating them, use `*` instead of `@`, e.g. `myVar=${myArray[*]}` (this separates elements with the first character of `IFS`, usually space).