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