Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Annlix
ShellCheck
提交
0f00de80
S
ShellCheck
项目概览
Annlix
/
ShellCheck
与 Fork 源项目一致
Fork自
镜像 / koalaman / ShellCheck
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
ShellCheck
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0f00de80
编写于
9月 05, 2015
作者:
V
Vidar Holen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support {n}>&1 named file descriptors.
上级
c808c9b6
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
37 addition
and
6 deletion
+37
-6
ShellCheck/Analytics.hs
ShellCheck/Analytics.hs
+23
-5
ShellCheck/Parser.hs
ShellCheck/Parser.hs
+14
-1
未找到文件。
ShellCheck/Analytics.hs
浏览文件 @
0f00de80
...
@@ -582,6 +582,7 @@ prop_checkBashisms24= verifyNot checkBashisms "trap mything int term"
...
@@ -582,6 +582,7 @@ prop_checkBashisms24= verifyNot checkBashisms "trap mything int term"
prop_checkBashisms25
=
verify
checkBashisms
"cat < /dev/tcp/host/123"
prop_checkBashisms25
=
verify
checkBashisms
"cat < /dev/tcp/host/123"
prop_checkBashisms26
=
verify
checkBashisms
"trap mything ERR SIGTERM"
prop_checkBashisms26
=
verify
checkBashisms
"trap mything ERR SIGTERM"
prop_checkBashisms27
=
verify
checkBashisms
"echo *[^0-9]*"
prop_checkBashisms27
=
verify
checkBashisms
"echo *[^0-9]*"
prop_checkBashisms28
=
verify
checkBashisms
"exec {n}>&2"
checkBashisms
_
=
bashism
checkBashisms
_
=
bashism
where
where
errMsg
id
s
=
err
id
2040
$
"In sh, "
++
s
++
" not supported, even when sh is actually bash."
errMsg
id
s
=
err
id
2040
$
"In sh, "
++
s
++
" not supported, even when sh is actually bash."
...
@@ -607,6 +608,7 @@ checkBashisms _ = bashism
...
@@ -607,6 +608,7 @@ checkBashisms _ = bashism
warnMsg
id
$
filter
(
/=
'|'
)
op
++
" is"
warnMsg
id
$
filter
(
/=
'|'
)
op
++
" is"
bashism
(
TA_Binary
id
"**"
_
_
)
=
warnMsg
id
"exponentials are"
bashism
(
TA_Binary
id
"**"
_
_
)
=
warnMsg
id
"exponentials are"
bashism
(
T_FdRedirect
id
"&"
(
T_IoFile
_
(
T_Greater
_
)
_
))
=
warnMsg
id
"&> is"
bashism
(
T_FdRedirect
id
"&"
(
T_IoFile
_
(
T_Greater
_
)
_
))
=
warnMsg
id
"&> is"
bashism
(
T_FdRedirect
id
(
'{'
:
_
)
_
)
=
warnMsg
id
"named file descriptors are"
bashism
(
T_IoFile
id
_
word
)
|
isNetworked
=
bashism
(
T_IoFile
id
_
word
)
|
isNetworked
=
warnMsg
id
"/dev/{tcp,udp} is"
warnMsg
id
"/dev/{tcp,udp} is"
where
where
...
@@ -1459,6 +1461,7 @@ isQuoteFreeNode strict tree t =
...
@@ -1459,6 +1461,7 @@ isQuoteFreeNode strict tree t =
isQuoteFreeElement
t
=
isQuoteFreeElement
t
=
case
t
of
case
t
of
T_Assignment
{}
->
return
True
T_Assignment
{}
->
return
True
T_FdRedirect
{}
->
return
True
_
->
Nothing
_
->
Nothing
-- Are any subnodes inherently self-quoting?
-- Are any subnodes inherently self-quoting?
...
@@ -2037,6 +2040,7 @@ prop_subshellAssignmentCheck14 = verifyNotTree subshellAssignmentCheck "#!/bin/k
...
@@ -2037,6 +2040,7 @@ prop_subshellAssignmentCheck14 = verifyNotTree subshellAssignmentCheck "#!/bin/k
prop_subshellAssignmentCheck15
=
verifyNotTree
subshellAssignmentCheck
"#!/bin/ksh
\n
cat foo | while read bar; do a=$bar; done
\n
echo
\"
$a
\"
"
prop_subshellAssignmentCheck15
=
verifyNotTree
subshellAssignmentCheck
"#!/bin/ksh
\n
cat foo | while read bar; do a=$bar; done
\n
echo
\"
$a
\"
"
prop_subshellAssignmentCheck16
=
verifyNotTree
subshellAssignmentCheck
"(set -e); echo $@"
prop_subshellAssignmentCheck16
=
verifyNotTree
subshellAssignmentCheck
"(set -e); echo $@"
prop_subshellAssignmentCheck17
=
verifyNotTree
subshellAssignmentCheck
"foo=${ { bar=$(baz); } 2>&1; }; echo $foo $bar"
prop_subshellAssignmentCheck17
=
verifyNotTree
subshellAssignmentCheck
"foo=${ { bar=$(baz); } 2>&1; }; echo $foo $bar"
prop_subshellAssignmentCheck18
=
verifyTree
subshellAssignmentCheck
"( exec {n}>&2; ); echo $n"
subshellAssignmentCheck
params
t
=
subshellAssignmentCheck
params
t
=
let
flow
=
variableFlow
params
let
flow
=
variableFlow
params
check
=
findSubshelled
flow
[(
"oops"
,
[]
)]
Map
.
empty
check
=
findSubshelled
flow
[(
"oops"
,
[]
)]
Map
.
empty
...
@@ -2055,7 +2059,7 @@ data StackData =
...
@@ -2055,7 +2059,7 @@ data StackData =
data
DataType
=
DataString
DataSource
|
DataArray
DataSource
data
DataType
=
DataString
DataSource
|
DataArray
DataSource
deriving
(
Show
)
deriving
(
Show
)
data
DataSource
=
SourceFrom
[
Token
]
|
SourceExternal
|
SourceDeclaration
data
DataSource
=
SourceFrom
[
Token
]
|
SourceExternal
|
SourceDeclaration
|
SourceInteger
deriving
(
Show
)
deriving
(
Show
)
data
VariableState
=
Dead
Token
String
|
Alive
deriving
(
Show
)
data
VariableState
=
Dead
Token
String
|
Alive
deriving
(
Show
)
...
@@ -2095,6 +2099,12 @@ leadType shell parents t =
...
@@ -2095,6 +2099,12 @@ leadType shell parents t =
Sh
->
True
Sh
->
True
Ksh
->
False
Ksh
->
False
isClosingFileOp
op
=
case
op
of
T_IoFile
_
(
T_GREATAND
_
)
(
T_NormalWord
_
[
T_Literal
_
"-"
])
->
True
T_IoFile
_
(
T_LESSAND
_
)
(
T_NormalWord
_
[
T_Literal
_
"-"
])
->
True
_
->
False
getModifiedVariables
t
=
getModifiedVariables
t
=
case
t
of
case
t
of
T_SimpleCommand
_
vars
[]
->
T_SimpleCommand
_
vars
[]
->
...
@@ -2117,8 +2127,11 @@ getModifiedVariables t =
...
@@ -2117,8 +2127,11 @@ getModifiedVariables t =
name
<-
getLiteralString
lhs
name
<-
getLiteralString
lhs
return
(
t
,
t
,
name
,
DataString
$
SourceFrom
[
rhs
])
return
(
t
,
t
,
name
,
DataString
$
SourceFrom
[
rhs
])
t
@
(
T_FdRedirect
_
(
'{'
:
var
)
op
)
->
-- {foo}>&2 modifies foo
[(
t
,
t
,
takeWhile
(
/=
'}'
)
var
,
DataString
SourceInteger
)
|
not
$
isClosingFileOp
op
]
t
@
(
T_CoProc
_
name
_
)
->
t
@
(
T_CoProc
_
name
_
)
->
[(
t
,
t
,
fromMaybe
"COPROC"
name
,
DataArray
Source
External
)]
[(
t
,
t
,
fromMaybe
"COPROC"
name
,
DataArray
Source
Integer
)]
--Points to 'for' rather than variable
--Points to 'for' rather than variable
T_ForIn
id
str
words
_
->
[(
t
,
t
,
str
,
DataString
$
SourceFrom
words
)]
T_ForIn
id
str
words
_
->
[(
t
,
t
,
str
,
DataString
$
SourceFrom
words
)]
...
@@ -2292,6 +2305,9 @@ getReferencedVariables t =
...
@@ -2292,6 +2305,9 @@ getReferencedVariables t =
TC_Unary
id
_
"-v"
token
->
getIfReference
t
token
TC_Unary
id
_
"-v"
token
->
getIfReference
t
token
TC_Unary
id
_
"-R"
token
->
getIfReference
t
token
TC_Unary
id
_
"-R"
token
->
getIfReference
t
token
t
@
(
T_FdRedirect
_
(
'{'
:
var
)
op
)
->
-- {foo}>&- references and closes foo
[(
t
,
t
,
takeWhile
(
/=
'}'
)
var
)
|
isClosingFileOp
op
]
x
->
getReferencedVariableCommand
x
x
->
getReferencedVariableCommand
x
where
where
-- Try to reduce false positives for unused vars only referenced from evaluated vars
-- Try to reduce false positives for unused vars only referenced from evaluated vars
...
@@ -2426,6 +2442,9 @@ prop_checkSpacefulness24= verifyTree checkSpacefulness "a='a b'; cat <<< $a"
...
@@ -2426,6 +2442,9 @@ prop_checkSpacefulness24= verifyTree checkSpacefulness "a='a b'; cat <<< $a"
prop_checkSpacefulness25
=
verifyTree
checkSpacefulness
"a='s/[0-9]//g'; sed $a"
prop_checkSpacefulness25
=
verifyTree
checkSpacefulness
"a='s/[0-9]//g'; sed $a"
prop_checkSpacefulness26
=
verifyTree
checkSpacefulness
"a='foo bar'; echo {1,2,$a}"
prop_checkSpacefulness26
=
verifyTree
checkSpacefulness
"a='foo bar'; echo {1,2,$a}"
prop_checkSpacefulness27
=
verifyNotTree
checkSpacefulness
"echo ${a:+'foo'}"
prop_checkSpacefulness27
=
verifyNotTree
checkSpacefulness
"echo ${a:+'foo'}"
prop_checkSpacefulness28
=
verifyNotTree
checkSpacefulness
"exec {n}>&1; echo $n"
prop_checkSpacefulness29
=
verifyNotTree
checkSpacefulness
"n=$(stuff); exec {n}>&-;"
prop_checkSpacefulness30
=
verifyTree
checkSpacefulness
"file='foo bar'; echo foo > $file;"
checkSpacefulness
params
t
=
checkSpacefulness
params
t
=
doVariableFlowAnalysis
readF
writeF
(
Map
.
fromList
defaults
)
(
variableFlow
params
)
doVariableFlowAnalysis
readF
writeF
(
Map
.
fromList
defaults
)
(
variableFlow
params
)
...
@@ -2451,9 +2470,8 @@ checkSpacefulness params t =
...
@@ -2451,9 +2470,8 @@ checkSpacefulness params t =
where
where
warning
=
"Double quote to prevent globbing and word splitting."
warning
=
"Double quote to prevent globbing and word splitting."
writeF
_
_
name
(
DataString
SourceExternal
)
=
do
writeF
_
_
name
(
DataString
SourceExternal
)
=
setSpaces
name
True
>>
return
[]
setSpaces
name
True
writeF
_
_
name
(
DataString
SourceInteger
)
=
setSpaces
name
False
>>
return
[]
return
[]
writeF
_
_
name
(
DataString
(
SourceFrom
vals
))
=
do
writeF
_
_
name
(
DataString
(
SourceFrom
vals
))
=
do
map
<-
get
map
<-
get
...
...
ShellCheck/Parser.hs
浏览文件 @
0f00de80
...
@@ -1401,6 +1401,13 @@ readIoFile = called "redirection" $ do
...
@@ -1401,6 +1401,13 @@ readIoFile = called "redirection" $ do
file
<-
readFilename
file
<-
readFilename
return
$
T_FdRedirect
id
""
$
T_IoFile
id
op
file
return
$
T_FdRedirect
id
""
$
T_IoFile
id
op
file
readIoVariable
=
try
$
do
char
'{'
x
<-
readVariableName
char
'}'
lookAhead
readIoFileOp
return
$
"{"
++
x
++
"}"
readIoNumber
=
try
$
do
readIoNumber
=
try
$
do
x
<-
many1
digit
<|>
string
"&"
x
<-
many1
digit
<|>
string
"&"
lookAhead
readIoFileOp
lookAhead
readIoFileOp
...
@@ -1410,9 +1417,11 @@ prop_readIoNumberRedirect = isOk readIoNumberRedirect "3>&2"
...
@@ -1410,9 +1417,11 @@ prop_readIoNumberRedirect = isOk readIoNumberRedirect "3>&2"
prop_readIoNumberRedirect2
=
isOk
readIoNumberRedirect
"2> lol"
prop_readIoNumberRedirect2
=
isOk
readIoNumberRedirect
"2> lol"
prop_readIoNumberRedirect3
=
isOk
readIoNumberRedirect
"4>&-"
prop_readIoNumberRedirect3
=
isOk
readIoNumberRedirect
"4>&-"
prop_readIoNumberRedirect4
=
isOk
readIoNumberRedirect
"&> lol"
prop_readIoNumberRedirect4
=
isOk
readIoNumberRedirect
"&> lol"
prop_readIoNumberRedirect5
=
isOk
readIoNumberRedirect
"{foo}>&2"
prop_readIoNumberRedirect6
=
isOk
readIoNumberRedirect
"{foo}<&-"
readIoNumberRedirect
=
do
readIoNumberRedirect
=
do
id
<-
getNextId
id
<-
getNextId
n
<-
readIoNumber
n
<-
readIo
Variable
<|>
readIo
Number
op
<-
readHereString
<|>
readHereDoc
<|>
readIoFile
op
<-
readHereString
<|>
readHereDoc
<|>
readIoFile
let
actualOp
=
case
op
of
T_FdRedirect
_
""
x
->
x
let
actualOp
=
case
op
of
T_FdRedirect
_
""
x
->
x
spacing
spacing
...
@@ -2326,6 +2335,10 @@ readScript = do
...
@@ -2326,6 +2335,10 @@ readScript = do
isWarning
p
s
=
parsesCleanly
p
s
==
Just
False
isWarning
p
s
=
parsesCleanly
p
s
==
Just
False
isOk
p
s
=
parsesCleanly
p
s
==
Just
True
isOk
p
s
=
parsesCleanly
p
s
==
Just
True
testParse
string
=
runIdentity
$
do
(
res
,
_
)
<-
runParser
(
mockedSystemInterface
[]
)
readScript
"-"
string
return
res
parsesCleanly
parser
string
=
runIdentity
$
do
parsesCleanly
parser
string
=
runIdentity
$
do
(
res
,
sys
)
<-
runParser
(
mockedSystemInterface
[]
)
(
res
,
sys
)
<-
runParser
(
mockedSystemInterface
[]
)
(
parser
>>
eof
>>
getState
)
"-"
string
(
parser
>>
eof
>>
getState
)
"-"
string
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录