Created SC2106 (markdown)

CH-DanReif
2018-04-19 14:48:44 -07:00
parent 5eb8832951
commit 1891a5bc86

53
SC2106.md Normal file

@@ -0,0 +1,53 @@
## SC2106: This only exits the subshell caused by the pipeline.
### Problematic code:
```sh
for i in a b c; do
echo hi | grep -q bye | break
done
```
### Correct code:
```sh
for i in a b c; do
echo hi | grep -q bye || break
done
```
### Rationale:
The most common cause of this issue is probably using a single `|` when `||` was intended. The reason this message appears, though, is that a construction like this, intended to surface a failure inside of a loop:
```sh
for i in a b c; do false | break; done; echo ${PIPESTATUS[@]}
```
may appear to work:
```
$ for i in a b c; do false | break; done; echo ${PIPESTATUS[@]}
1 0
```
What's actually happening, though, becomes clear if we add some `echo`s; the entire loop completes, and the `break` has no effect.
```sh
$ for i in a b c; do echo $i; false | break; done; echo ${PIPESTATUS[@]}
a
b
c
1 0
$ for i in a b c; do false | break; echo $i; done; echo ${PIPESTATUS[@]}
a
b
c
0
```
Because bash processes pipelines by creating subshells, control statements like `break` only take effect in the subshell.
### Related resources:
* Contrast with the related, but different, problem in [this link](https://unix.stackexchange.com/questions/166546/bash-cannot-break-out-of-piped-while-read-loop-process-substitution-works).
* [Bash Reference Manual: Pipelines](https://www.gnu.org/software/bash/manual/bash.html#Pipelines), esp.:
> Each command in a pipeline is executed in its own subshell.