Created SC2207 (markdown)

koalaman
2017-04-02 14:27:48 -07:00
parent 04ba5e2811
commit c91f068550

50
SC2207.md Normal file

@@ -0,0 +1,50 @@
## Prefer mapfile or read -a to split command output (or quote to avoid splitting).
### Problematic code:
```sh
array=( $(mycommand) )
```
### Correct code:
If the output should be a single element:
```sh
array=( "$(mycommand)" )
```
If it outputs multiple lines, each of which should be an element:
```sh
# For bash
mapfile -t array < <(mycommand)
# For ksh
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:
```sh
# For bash
IFS=" " read -r -a array <<< "$(mycommand)"
# For ksh
IFS=" " read -r -A array <<< "$(mycommand)"
```
### Rationale:
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 the command output should become a single array element, quote it.
* If you want to split the output into lines or words, use `mapfile`, `read -ra` and/or `while` loops as appropriate.
This prevents the shell from doing unwanted splitting and glob expansion, and therefore avoiding problems with output containing spaces or special characters.
### Exceptions:
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.