mirror of
https://github.com/koalaman/shellcheck.git
synced 2025-10-03 19:29:44 +08:00
Created SC2106 (markdown)
53
SC2106.md
Normal file
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.
|
Reference in New Issue
Block a user