mirror of
https://github.com/koalaman/shellcheck.git
synced 2025-10-03 19:29:44 +08:00
Created SC2031 (markdown)
60
SC2031.md
Normal file
60
SC2031.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# var was modified in a subshell. That change might be lost.
|
||||
|
||||
### Problematic code:
|
||||
|
||||
There are many ways of accidentally creating subshells, but a common one is piping to a loop:
|
||||
|
||||
n=0
|
||||
printf "%s\n" {1..10} | while read i; do (( n+=i )); done
|
||||
echo $n
|
||||
|
||||
### Correct code:
|
||||
|
||||
# Bash specific:
|
||||
n=0
|
||||
while read i; do (( n+=i )); done < <(printf "%s\n" {1..10})
|
||||
echo $n
|
||||
|
||||
In `sh`, a temp file can be used instead of process substitution.
|
||||
|
||||
### Rationale:
|
||||
|
||||
Variables set in subshells are not available outside the subshell. This is a wide topic, and better described on the [Wooledge Bash Wiki](http://mywiki.wooledge.org/BashFAQ/024).
|
||||
|
||||
Here are some constructs that cause subshells (shellcheck may not warn about all of them). In each case, you can replace `subshell1` by a command or function that sets a variable, e.g. simply `var=foo`, and the variable will appear to be unset after the command is run. Similarly, you can replace `regular` with `var=foo`, and it will be set afterwards:
|
||||
|
||||
Pipelines:
|
||||
|
||||
subshell1 | subshell2 | subshell3 # Bash, Dash, Ash
|
||||
subshell1 | subshell2 | regular # Ksh, Zsh
|
||||
|
||||
Command substitution:
|
||||
|
||||
regular "$(subshell1)" "`subshell2`"
|
||||
|
||||
Process substitution:
|
||||
|
||||
regular <(subshell1) >(subshell2)
|
||||
|
||||
Some forms of grouping:
|
||||
|
||||
( subshell )
|
||||
{ regular; }
|
||||
|
||||
Backgrounding:
|
||||
|
||||
subshell1 &
|
||||
subshell2 &
|
||||
|
||||
Anything executed by external processes:
|
||||
|
||||
find . -exec subshell1 {} \;
|
||||
find . -print0 | xargs -0 subshell2
|
||||
sudo subshell3
|
||||
su -c subshell4
|
||||
|
||||
This applies not only to setting variables, but also setting shell options and changing directories.
|
||||
|
||||
### Contraindications
|
||||
|
||||
You can ignore this error if you don't care that the changes aren't reflected, because work on the value branches and shouldn't be recombined.
|
Reference in New Issue
Block a user