Warn when piping/redirecting to mv/cp/echo/etc (#921)
This commit is contained in:
parent
a3c6aff0fb
commit
5bd33dbf92
|
@ -164,6 +164,7 @@ nodeChecks = [
|
||||||
,checkGlobAsCommand
|
,checkGlobAsCommand
|
||||||
,checkFlagAsCommand
|
,checkFlagAsCommand
|
||||||
,checkEmptyCondition
|
,checkEmptyCondition
|
||||||
|
,checkPipeToNowhere
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -363,9 +364,6 @@ checkPipePitfalls _ (T_Pipeline id _ commands) = do
|
||||||
]) $ warn (getId find) 2038
|
]) $ warn (getId find) 2038
|
||||||
"Use -print0/-0 or -exec + to allow for non-alphanumeric filenames."
|
"Use -print0/-0 or -exec + to allow for non-alphanumeric filenames."
|
||||||
|
|
||||||
for ["?", "echo"] $
|
|
||||||
\(_:echo:_) -> info (getId echo) 2008 "echo doesn't read from stdin, are you sure you should be piping to it?"
|
|
||||||
|
|
||||||
for' ["ps", "grep"] $
|
for' ["ps", "grep"] $
|
||||||
\x -> info x 2009 "Consider using pgrep instead of grepping ps output."
|
\x -> info x 2009 "Consider using pgrep instead of grepping ps output."
|
||||||
|
|
||||||
|
@ -2786,5 +2784,53 @@ checkEmptyCondition _ t = case t of
|
||||||
TC_Empty id _ -> style id 2212 "Use 'false' instead of empty [/[[ conditionals."
|
TC_Empty id _ -> style id 2212 "Use 'false' instead of empty [/[[ conditionals."
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
|
|
||||||
|
prop_checkPipeToNowhere1 = verify checkPipeToNowhere "foo | echo bar"
|
||||||
|
prop_checkPipeToNowhere2 = verify checkPipeToNowhere "basename < file.txt"
|
||||||
|
prop_checkPipeToNowhere3 = verify checkPipeToNowhere "printf 'Lol' <<< str"
|
||||||
|
prop_checkPipeToNowhere4 = verify checkPipeToNowhere "printf 'Lol' << eof\nlol\neof\n"
|
||||||
|
prop_checkPipeToNowhere5 = verifyNot checkPipeToNowhere "echo foo | xargs du"
|
||||||
|
prop_checkPipeToNowhere6 = verifyNot checkPipeToNowhere "ls | echo $(cat)"
|
||||||
|
prop_checkPipeToNowhere7 = verifyNot checkPipeToNowhere "echo foo | var=$(cat) ls"
|
||||||
|
checkPipeToNowhere :: Parameters -> Token -> WriterT [TokenComment] Identity ()
|
||||||
|
checkPipeToNowhere _ t =
|
||||||
|
case t of
|
||||||
|
T_Pipeline _ _ (first:rest) -> mapM_ checkPipe rest
|
||||||
|
T_Redirecting _ redirects cmd -> when (any redirectsStdin redirects) $ checkRedir cmd
|
||||||
|
_ -> return ()
|
||||||
|
where
|
||||||
|
checkPipe redir = potentially $ do
|
||||||
|
cmd <- getCommand redir
|
||||||
|
name <- getCommandBasename cmd
|
||||||
|
guard $ name `elem` nonReadingCommands
|
||||||
|
guard . not $ hasAdditionalConsumers cmd
|
||||||
|
return $ warn (getId cmd) 2216 $
|
||||||
|
"Piping to '" ++ name ++ "', a command that doesn't read stdin. Wrong command or missing xargs?"
|
||||||
|
|
||||||
|
checkRedir cmd = potentially $ do
|
||||||
|
name <- getCommandBasename cmd
|
||||||
|
guard $ name `elem` nonReadingCommands
|
||||||
|
guard . not $ hasAdditionalConsumers cmd
|
||||||
|
return $ warn (getId cmd) 2217 $
|
||||||
|
"Redirecting to '" ++ name ++ "', a command that doesn't read stdin. Bad quoting or missing xargs?"
|
||||||
|
|
||||||
|
-- Could any words in a SimpleCommand consume stdin (e.g. echo "$(cat)")?
|
||||||
|
hasAdditionalConsumers t = fromMaybe True $ do
|
||||||
|
doAnalysis (guard . not . mayConsume) t
|
||||||
|
return False
|
||||||
|
|
||||||
|
mayConsume t =
|
||||||
|
case t of
|
||||||
|
T_ProcSub {} -> True
|
||||||
|
T_Backticked {} -> True
|
||||||
|
T_DollarExpansion {} -> True
|
||||||
|
_ -> False
|
||||||
|
|
||||||
|
redirectsStdin t =
|
||||||
|
case t of
|
||||||
|
T_FdRedirect _ _ (T_IoFile _ T_Less {} _) -> True
|
||||||
|
T_FdRedirect _ _ T_HereDoc {} -> True
|
||||||
|
T_FdRedirect _ _ T_HereString {} -> True
|
||||||
|
_ -> False
|
||||||
|
|
||||||
return []
|
return []
|
||||||
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])
|
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])
|
||||||
|
|
|
@ -77,6 +77,14 @@ commonCommands = [
|
||||||
"zcat"
|
"zcat"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
nonReadingCommands = [
|
||||||
|
"alias", "basename", "bg", "cal", "cd", "chgrp", "chmod", "chown",
|
||||||
|
"cp", "du", "echo", "export", "fg", "fuser", "getconf", "getopt",
|
||||||
|
"getopts", "ipcrm", "ipcs", "jobs", "kill", "ln", "ls", "locale", "mv",
|
||||||
|
"nice", "printf", "ps", "pwd", "renice", "rm", "rmdir", "set", "sleep",
|
||||||
|
"touch", "trap", "ulimit", "unalias", "uname"
|
||||||
|
]
|
||||||
|
|
||||||
sampleWords = [
|
sampleWords = [
|
||||||
"alpha", "bravo", "charlie", "delta", "echo", "foxtrot",
|
"alpha", "bravo", "charlie", "delta", "echo", "foxtrot",
|
||||||
"golf", "hotel", "india", "juliett", "kilo", "lima", "mike",
|
"golf", "hotel", "india", "juliett", "kilo", "lima", "mike",
|
||||||
|
|
Loading…
Reference in New Issue