mirror of
https://github.com/koalaman/shellcheck.git
synced 2025-10-03 19:29:44 +08:00
Created SC2302 (markdown)
67
SC2302.md
Normal file
67
SC2302.md
Normal file
@@ -0,0 +1,67 @@
|
||||
## This loops over values. To loop over keys, use "${!array[@]}".
|
||||
|
||||
Plus companion warning [[SC2303]]: `i is an array value, not a key. Use directly or loop over keys instead.`
|
||||
|
||||
### Problematic code:
|
||||
|
||||
```sh
|
||||
array=(foo bar)
|
||||
for i in "${array[@]}"
|
||||
do
|
||||
echo "Value is ${array[$i]}"
|
||||
done
|
||||
```
|
||||
|
||||
### Correct code:
|
||||
|
||||
Either loop over values
|
||||
|
||||
```sh
|
||||
for i in "${array[@]}"
|
||||
do
|
||||
echo "Value is $i"
|
||||
done
|
||||
```
|
||||
|
||||
or loop over keys:
|
||||
|
||||
```sh
|
||||
for i in "${!array[@]}"
|
||||
do
|
||||
echo "Key is $i"
|
||||
echo "Value is ${array[$i]}"
|
||||
done
|
||||
```
|
||||
|
||||
### Rationale:
|
||||
|
||||
ShellCheck found a `for` loop over array *values*, where the variable is used as an array *key*.
|
||||
|
||||
In the problematic example, the loop will print `Value is foo` twice. On the second iteration, `i=bar`, and `bar` is unset and considered zero, so `${array[$i]}` becomes `${array[bar]}` becomes `${array[0]}` becomes `foo`.
|
||||
|
||||
If you don't care about the key, simply loop over array values and use `$i` to refer to the array value, like in the first correct example.
|
||||
|
||||
If you do want the key, loop over array keys with `"${!array[@]}"`, use `$i` to refer to the array key, and `${array[$i]}` to refer to the array value.
|
||||
|
||||
### Exceptions:
|
||||
|
||||
If you do want to use values from the arrays as keys in the same array, you can [[ignore]] these messages with a directive:
|
||||
|
||||
```sh
|
||||
declare -A fatherOf=(
|
||||
["Eric Bloodaxe"]="Harald Fairhair"
|
||||
["Harald Fairhair"]="Halfdan the Black"
|
||||
["Halfdan the Black"]="Gudrød the Hunter"
|
||||
["Gudrød the Hunter"]="Halfdan the Mild"
|
||||
)
|
||||
|
||||
# shellcheck disable=SC2302,SC23203
|
||||
for i in "${fatherOf[@]}"
|
||||
do
|
||||
echo "${fatherOf[$i]:-(missing)} begat $i"
|
||||
done
|
||||
```
|
||||
|
||||
### Related resources:
|
||||
|
||||
* Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc!
|
Reference in New Issue
Block a user