Warn about timing pipelines and compound commands in sh/dash.

This commit is contained in:
Vidar Holen 2016-03-19 16:14:55 -07:00
parent 2957fb64c9
commit c91083354f
2 changed files with 32 additions and 4 deletions

View File

@ -73,11 +73,13 @@ checksFor Sh = [
checkBashisms checkBashisms
,checkTimeParameters ,checkTimeParameters
,checkForDecimals ,checkForDecimals
,checkTimedCommand
] ]
checksFor Dash = [ checksFor Dash = [
checkBashisms checkBashisms
,checkForDecimals ,checkForDecimals
,checkLocalScope ,checkLocalScope
,checkTimedCommand
] ]
checksFor Ksh = [ checksFor Ksh = [
checkEchoSed checkEchoSed
@ -1107,8 +1109,8 @@ checkStderrRedirect params redir@(T_Redirecting _ [
checkStderrRedirect _ _ = return () checkStderrRedirect _ _ = return ()
lt x = trace ("FAILURE " ++ show x) x lt x = trace ("Tracing " ++ show x) x
ltt t = trace ("FAILURE " ++ show t) ltt t = trace ("Tracing " ++ show t)
prop_checkSingleQuotedVariables = verify checkSingleQuotedVariables "echo '$foo'" prop_checkSingleQuotedVariables = verify checkSingleQuotedVariables "echo '$foo'"
@ -1863,6 +1865,32 @@ checkTimeParameters _ = checkUnqualifiedCommand "time" f where
info (getId cmd) 2023 "The shell may override 'time' as seen in man time(1). Use 'command time ..' for that one." info (getId cmd) 2023 "The shell may override 'time' as seen in man time(1). Use 'command time ..' for that one."
f _ _ = return () f _ _ = return ()
prop_checkTimedCommand1 = verify checkTimedCommand "time -p foo | bar"
prop_checkTimedCommand2 = verify checkTimedCommand "time ( foo; bar; )"
prop_checkTimedCommand3 = verifyNot checkTimedCommand "time sleep 1"
checkTimedCommand _ = checkUnqualifiedCommand "time" f where
f c args@(_:_) = do
let cmd = last args
when (isPiped cmd) $
warn (getId c) 2176 "'time' is undefined for pipelines. time single stage or sh -c instead."
when (isSimple cmd == Just False) $
warn (getId cmd) 2177 "'time' is undefined for compound commands, time sh -c instead."
f _ _ = return ()
isPiped cmd =
case cmd of
T_Pipeline _ _ (_:_:_) -> True
_ -> False
getCommand cmd =
case cmd of
T_Pipeline _ _ ((T_Redirecting _ _ a):_) -> return a
_ -> fail ""
isSimple cmd = do
innerCommand <- getCommand cmd
case innerCommand of
T_SimpleCommand {} -> return True
_ -> return False
prop_checkTestRedirects1 = verify checkTestRedirects "test 3 > 1" prop_checkTestRedirects1 = verify checkTestRedirects "test 3 > 1"
prop_checkTestRedirects2 = verifyNot checkTestRedirects "test 3 \\> 1" prop_checkTestRedirects2 = verifyNot checkTestRedirects "test 3 \\> 1"
prop_checkTestRedirects3 = verify checkTestRedirects "/usr/bin/test $var > $foo" prop_checkTestRedirects3 = verify checkTestRedirects "/usr/bin/test $var > $foo"

View File

@ -4,12 +4,12 @@
# 'cabal test' remains the source of truth. # 'cabal test' remains the source of truth.
( (
var=$(echo 'liftM and $ sequence [ShellCheck.Analytics.runTests, ShellCheck.Parser.runTests, ShellCheck.Checker.runTests]' | cabal repl | tee /dev/stderr) var=$(echo 'liftM and $ sequence [ShellCheck.Analytics.runTests, ShellCheck.Parser.runTests, ShellCheck.Checker.runTests]' | cabal repl 2>&1 | tee /dev/stderr)
if [[ $var == *$'\nTrue'* ]] if [[ $var == *$'\nTrue'* ]]
then then
exit 0 exit 0
else else
grep -C 3 "Fail" <<< "$var" grep -C 3 -e "Fail" -e "Tracing" <<< "$var"
exit 1 exit 1
fi fi
) 2>&1 ) 2>&1