mirror of
https://github.com/koalaman/shellcheck
synced 2025-07-08 05:51:09 -07:00
Improve warnings about unnecessary subshells (fixes #2169)
This commit is contained in:
parent
10817533d6
commit
f5fd9c2fed
1 changed files with 29 additions and 5 deletions
|
@ -3742,21 +3742,27 @@ checkForLoopGlobVariables _ t =
|
||||||
suggest t = info (getId t) 2231
|
suggest t = info (getId t) 2231
|
||||||
"Quote expansions in this for loop glob to prevent wordsplitting, e.g. \"$dir\"/*.txt ."
|
"Quote expansions in this for loop glob to prevent wordsplitting, e.g. \"$dir\"/*.txt ."
|
||||||
|
|
||||||
|
|
||||||
prop_checkSubshelledTests1 = verify checkSubshelledTests "a && ( [ b ] || ! [ c ] )"
|
prop_checkSubshelledTests1 = verify checkSubshelledTests "a && ( [ b ] || ! [ c ] )"
|
||||||
prop_checkSubshelledTests2 = verify checkSubshelledTests "( [ a ] )"
|
prop_checkSubshelledTests2 = verify checkSubshelledTests "( [ a ] )"
|
||||||
prop_checkSubshelledTests3 = verify checkSubshelledTests "( [ a ] && [ b ] || test c )"
|
prop_checkSubshelledTests3 = verify checkSubshelledTests "( [ a ] && [ b ] || test c )"
|
||||||
prop_checkSubshelledTests4 = verify checkSubshelledTests "( [ a ] && { [ b ] && [ c ]; } )"
|
prop_checkSubshelledTests4 = verify checkSubshelledTests "( [ a ] && { [ b ] && [ c ]; } )"
|
||||||
|
prop_checkSubshelledTests5 = verifyNot checkSubshelledTests "( [[ ${var:=x} = y ]] )"
|
||||||
|
prop_checkSubshelledTests6 = verifyNot checkSubshelledTests "( [[ $((i++)) = 10 ]] )"
|
||||||
|
prop_checkSubshelledTests7 = verifyNot checkSubshelledTests "( [[ $((i+=1)) = 10 ]] )"
|
||||||
|
prop_checkSubshelledTests8 = verify checkSubshelledTests "# shellcheck disable=SC2234\nf() ( [[ x ]] )"
|
||||||
|
|
||||||
checkSubshelledTests params t =
|
checkSubshelledTests params t =
|
||||||
case t of
|
case t of
|
||||||
T_Subshell id list | all isTestStructure list ->
|
T_Subshell id list | all isTestStructure list && (not (hasAssignment t)) ->
|
||||||
case () of
|
case () of
|
||||||
-- Special case for if (test) and while (test)
|
-- Special case for if (test) and while (test)
|
||||||
_ | isCompoundCondition (getPath (parentMap params) t) ->
|
_ | isCompoundCondition (getPath (parentMap params) t) ->
|
||||||
style id 2233 "Remove superfluous (..) around condition."
|
style id 2233 "Remove superfluous (..) around condition to avoid subshell overhead."
|
||||||
|
|
||||||
-- Special case for ([ x ])
|
-- Special case for ([ x ]), except for func() ( [ x ] )
|
||||||
_ | isSingleTest list ->
|
_ | isSingleTest list && (not $ isFunctionBody (getPath (parentMap params) t)) ->
|
||||||
style id 2234 "Remove superfluous (..) around test command."
|
style id 2234 "Remove superfluous (..) around test command to avoid subshell overhead."
|
||||||
|
|
||||||
-- General case for ([ x ] || [ y ] && etc)
|
-- General case for ([ x ] || [ y ] && etc)
|
||||||
_ -> style id 2235 "Use { ..; } instead of (..) to avoid subshell overhead."
|
_ -> style id 2235 "Use { ..; } instead of (..) to avoid subshell overhead."
|
||||||
|
@ -3768,6 +3774,11 @@ checkSubshelledTests params t =
|
||||||
[c] | isTestCommand c -> True
|
[c] | isTestCommand c -> True
|
||||||
_ -> False
|
_ -> False
|
||||||
|
|
||||||
|
isFunctionBody path =
|
||||||
|
case path of
|
||||||
|
(_:f:_) -> isFunction f
|
||||||
|
_ -> False
|
||||||
|
|
||||||
isTestStructure t =
|
isTestStructure t =
|
||||||
case t of
|
case t of
|
||||||
T_Banged _ t -> isTestStructure t
|
T_Banged _ t -> isTestStructure t
|
||||||
|
@ -3798,6 +3809,19 @@ checkSubshelledTests params t =
|
||||||
T_UntilExpression {} : _ -> True
|
T_UntilExpression {} : _ -> True
|
||||||
_ -> False
|
_ -> False
|
||||||
|
|
||||||
|
hasAssignment t = isNothing $ doAnalysis guardNotAssignment t
|
||||||
|
guardNotAssignment t =
|
||||||
|
case t of
|
||||||
|
TA_Assignment {} -> Nothing
|
||||||
|
TA_Unary _ s _ -> guard . not $ "++" `isInfixOf` s || "--" `isInfixOf` s
|
||||||
|
T_DollarBraced _ _ l ->
|
||||||
|
let str = concat $ oversimplify l
|
||||||
|
modifier = getBracedModifier str
|
||||||
|
in
|
||||||
|
guard . not $ "=" `isPrefixOf` modifier || ":=" `isPrefixOf` modifier
|
||||||
|
T_DollarBraceCommandExpansion {} -> Nothing
|
||||||
|
_ -> Just ()
|
||||||
|
|
||||||
-- Skip any parent of a T_Subshell until we reach something interesting
|
-- Skip any parent of a T_Subshell until we reach something interesting
|
||||||
skippable t =
|
skippable t =
|
||||||
case t of
|
case t of
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue