Skip to content

Commit fadb589

Browse files
committed
Also detect 'grep -m n' and 'grep -L'
1 parent e9bd7ce commit fadb589

1 file changed

Lines changed: 12 additions & 2 deletions

File tree

src/ShellCheck/Checks/Commands.hs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ prop_checkGrepQPipefail2 = verify checkGrepQPipefail "set -o pipefail; cat file
408408
prop_checkGrepQPipefail3 = verify checkGrepQPipefail "set -o pipefail; cat file | grep -iq pattern"
409409
prop_checkGrepQPipefail4 = verify checkGrepQPipefail "set -o pipefail; cmd1 | cmd2 | grep -q pattern"
410410
prop_checkGrepQPipefail5 = verify checkGrepQPipefail "set -euo pipefail; cmd | grep -q foo"
411+
prop_checkGrepQPipefail6 = verify checkGrepQPipefail "set -o pipefail; cmd | grep -m 2 foo | cmd2"
412+
prop_checkGrepQPipefail7 = verify checkGrepQPipefail "set -o pipefail; cmd | grep -L foo | cmd2"
413+
411414
prop_checkGrepQPipefailN1 = verifyNot checkGrepQPipefail "cat file | grep -q pattern"
412415
prop_checkGrepQPipefailN2 = verifyNot checkGrepQPipefail "set -o pipefail; grep -q pattern file"
413416
prop_checkGrepQPipefailN3 = verifyNot checkGrepQPipefail "set -o pipefail; cat file | grep pattern"
@@ -427,18 +430,25 @@ checkEgrepQPipefail = CommandCheck (Basename "egrep") checkQuietGrepInPipefailIm
427430
prop_checkFgrepQPipefail1 = verify checkFgrepQPipefail "set -o pipefail; cat file | fgrep -q pattern"
428431
checkFgrepQPipefail = CommandCheck (Basename "fgrep") checkQuietGrepInPipefailImpl
429432

433+
-- Catches occurrences of "grep -q" and variants inside of pipes under pipefail.
430434
checkQuietGrepInPipefailImpl cmd = do
431435
pipefail <- asks hasPipefail
432436
astPath <- getPathM cmd
433437
sequence_ $ do
434438
guard pipefail
435-
opts <- parseGrepOpts $ arguments cmd
436-
guard $ any (\(flag, _) -> flag == "q" || flag == "quiet") opts
439+
opts <- map fst <$> parseGrepOpts (arguments cmd)
440+
guard $ any isEarlyExitFlag opts
437441
_simpleCmd:grepRedirectingCmd:parentNodes <- Just $ NE.toList astPath
438442
T_Pipeline _ _ (_first:redirectingCmds) <- listToMaybe parentNodes
439443
guard $ any (\node -> getId node == getId grepRedirectingCmd) redirectingCmds
440444
return $ warn (getId cmd) 2337 warnMsg
441445
where
446+
-- Contains "L", even though BSD grep does not exit early with this flag,
447+
-- but GNU grep does. This is consistent with the linter practice of warning
448+
-- about potential problems, while also allowing users to disable specific
449+
-- linter checks locally.
450+
earlyExitFlags = ["q", "quiet", "m", "max-count", "L"]
451+
isEarlyExitFlag name = name `elem` earlyExitFlags
442452
parseGrepOpts = getOpts (True, True)
443453
"cilLnoqsvwxhHrRbaEFGPe:f:m:A:B:C:d:D:"
444454
(map (\name -> (name, True)) longOptionsConsumingParameter)

0 commit comments

Comments
 (0)