mirror of
https://github.com/koalaman/shellcheck
synced 2025-07-06 21:11:35 -07:00
Warn when $? refers to echo or condition (ref #2541)
This commit is contained in:
parent
b261ec24f9
commit
5cf6e01ce9
4 changed files with 42 additions and 0 deletions
|
@ -205,6 +205,7 @@ nodeChecks = [
|
|||
,checkBatsTestDoesNotUseNegation
|
||||
,checkCommandIsUnreachable
|
||||
,checkSpacefulnessCfg
|
||||
,checkOverwrittenExitCode
|
||||
]
|
||||
|
||||
optionalChecks = map fst optionalTreeChecks
|
||||
|
@ -4876,5 +4877,41 @@ checkCommandIsUnreachable params t =
|
|||
_ -> return ()
|
||||
where id = getId t
|
||||
|
||||
|
||||
prop_checkOverwrittenExitCode1 = verify checkOverwrittenExitCode "x; [ $? -eq 1 ] || [ $? -eq 2 ]"
|
||||
prop_checkOverwrittenExitCode2 = verifyNot checkOverwrittenExitCode "x; [ $? -eq 1 ]"
|
||||
prop_checkOverwrittenExitCode3 = verify checkOverwrittenExitCode "x; echo \"Exit is $?\"; [ $? -eq 0 ]"
|
||||
prop_checkOverwrittenExitCode4 = verifyNot checkOverwrittenExitCode "x; [ $? -eq 0 ]"
|
||||
checkOverwrittenExitCode params t =
|
||||
case t of
|
||||
T_DollarBraced id _ val | getLiteralString val == Just "?" -> check id
|
||||
_ -> return ()
|
||||
where
|
||||
check id = sequence_ $ do
|
||||
state <- CF.getIncomingState (cfgAnalysis params) id
|
||||
let exitCodeIds = CF.exitCodes state
|
||||
guard . not $ S.null exitCodeIds
|
||||
|
||||
let idToToken = idMap params
|
||||
exitCodeTokens <- sequence $ map (\k -> Map.lookup k idToToken) $ S.toList exitCodeIds
|
||||
return $ do
|
||||
when (all isCondition exitCodeTokens) $
|
||||
warn id 2319 "This $? refers to a condition, not a command. Assign to a variable to avoid it being overwritten."
|
||||
when (all isPrinting exitCodeTokens) $
|
||||
warn id 2320 "This $? refers to echo/printf, not a previous command. Assign to variable to avoid it being overwritten."
|
||||
|
||||
isCondition t =
|
||||
case t of
|
||||
T_Condition {} -> True
|
||||
T_SimpleCommand {} -> getCommandName t == Just "test"
|
||||
_ -> False
|
||||
|
||||
isPrinting t =
|
||||
case getCommandBasename t of
|
||||
Just "echo" -> True
|
||||
Just "printf" -> True
|
||||
_ -> False
|
||||
|
||||
|
||||
return []
|
||||
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue