我有这个变量
start=$1;
end=$2;
sn=${#start}
en=${#end}
如果:
if ( [ $# -eq 2 ] )
then
elif ( [ $sn -ne 3 ] && [ -n "$(printf '%s\n' "$start" | sed 's/[0-9]//g') " ] );
then
echo "Incorrect format"
exit 1
elif ( [ $en -ne 3 ] && [ -n "$(printf '%s\n' "$end" | sed 's/[0-9]//g') " ] );
then
echo "Incorrect format"
exit 1
else
echo "Correct format"
exit 1
fi
我在第一个 elif 时感到意外,我想检查用户提供的参数,并且它们只能由 3 位数字组成。
答案1
if ( [ $# -eq 2 ] )
then
elif
正如杰夫的回答所说,第一个if
条件是缺少命令部分。 Bash 和 Dash 给出的错误消息有点模糊,似乎它们直接来自解析器,并且他们没有费心在那里添加更用户友好的消息。
如果您不想在分支内执行任何操作,您仍然需要在那里添加一些命令。我建议true
,这没有任何作用。
解决这个问题,shellcheck.net给出了更多观察结果:
if ( [ $# -eq 2 ] )
^-- SC2233: Remove superfluous (..) around condition.
括号启动一个子 shell,这在这里不是必需的(并且涉及额外的开销,例如在 Bash 中分叉子进程)。
... [ -n "$(printf '%s\n' "$start" | sed 's/[0-9]//g') " ]
>> ^--
SC2157: Argument to -n is always true due to literal strings.
您引用了命令替换,很好!但最后你还有一个额外的空间。无论命令替换输出什么,-n
由于存在空格,的参数永远不会为空。
(它还指出了引用$sn
和,这将是一件需要小心的事情,但如果您知道不包含任何数字,$en
则实际上没有必要。)IFS
也就是说,我不确定条件是否仍然合适。你说:
我想检查用户提供的参数,它们只能由 3 位数字组成。
sn
但请注意,下面的测试仅捕获不是三个的情况,另外除了数字之外还有其他字符,即它通过abc
和1234
,并且仅拒绝,例如abcd
。你想要一个或者条件 , ||
, 代替和。
if [ $sn -ne 3 ] && [ -n "$(printf '%s\n' "$start" | sed 's/[0-9]//g')" ]; then
echo reject
或者你可以只使用case
和模式匹配:
case "$start" in
[0-9][0-9][0-9]) echo "'$start' is ok";;
*) echo "'$start' is invalid"; exit 1;;
esac
答案2
在第一个的“真实”情况下,您没有任何陈述if
:
if ( [ $# -eq 2 ] )
then
## <-- HERE
elif ...
引用bash手册:
if 命令的语法为:
if test-commands; then consequent-commands; [elif more-test-commands; then more-consequents;] [else alternate-consequents;] fi
其中重要的一点是consequent-commands
.