我正在修改用于测试报告编写器的脚本。报告编写器采用可选的 --from 和 --to 标志来指定开始日期和结束日期。我想修改启动报告编写器的脚本函数,以便其日期参数也是可选的。
可悲的是,该函数已经有可选参数,所以我正在尝试测试参数是否为日期使用正确的格式(我们使用 nn/nn/nnnn(。
因此,我正在回显候选字符串并使用 grep 检查它的格式是否正确。除非它不起作用。
这是函数的摘录
# If the next argument looks like a date, consume it and use it to define
# the report start date
looksLikeDate=$(echo $1 | grep -e '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]')
echo from -
echo $1: "$1"
echo looksLikeDate: "$looksLikeDate"
if [ -n $looksLikeDate ]
then
echo "-n: true"
FROMFLAG="--from $1"
shift 1
else
echo "-n : false"
FROMFLAG=""
fi
# If the next argument looks like a date, consume it and use it to define
# the report end date
looksLikeDate=$(echo $1 | grep -e '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]')
echo to -
echo $1: "$1"
echo looksLikeDate: "$looksLikeDate"
if [ -n $looksLikeDate ]
then
echo "-n: true"
TOFLAG="--to $1"
shift 1
else
echo "-n: false"
TOFLAG=""
fi
。这是带有日期的输出...
from -
$1: "09/02/2018"
looksLikeDate: "09/02/2018"
-n: true
to -
$1: "09/02/2018"
looksLikeDate: "09/02/2018"
-n: true
。而且没有...
from -
$1: ""
looksLikeDate: ""
-n: true
to -
$1: ""
looksLikeDate: ""
-n: true
。我错过了什么?我希望由于looksLikeDate
是可证明的空的,[ -n $looksLikeDate ]
会返回false
并且代码将沿着if
语句的else
路径前进。
更新:
自从发布以来,我突然想到最简单的事情是不查看函数中的参数,而是让调用者传递参数--from
并--to
参数,以便我可以简单地$*
传递给报告编写器,就像对现有可选参数所做的那样。
非常感谢您的阅读;我仍然很好奇为什么发布的代码不起作用。
那是因为你没有引用你的变量!使用更多引号!
所以这是正在发生的事情:当 Bash 看到
[ -n $looksLikeDate ]
它执行参数扩展、全局扩展、引号删除等,最后看到这个(我在每行放一个标记(:
[
-n
]
并且您会看到缺少$looksLikeDate
部分,因为参数$looksLikeDate
在引号删除步骤之前扩展到空字符串。然后 Bash 执行内置[
,并使用结束]
,这相当于以下命令:
test -n
现在查看内置test
的参考手册,您将阅读:
1 个参数
当且仅当参数不为 null 时,表达式为 true。
在这里,参数是-n
,因此不是 nil,因此表达式为真。
所以请记住:
使用更多报价! 引用您所有的变量扩展!
此特定行应如下所示:
[ -n "$looksLikeDate" ]
另一种可能性是使用[[
关键字:
[[ -n $looksLikeDate ]]
但无论如何,引用你所有的扩展!
另外,您不需要外部工具grep
,您可以使用Bash的内部正则表达式引擎,或者更好的是:
if [[ $1 = [[:digit:]][[:digit:]]/[[:digit:]][[:digit:]]/[[:digit:]][[:digit:]][[:digit:]][[:digit:]] ]]; then
这有点长,所以使用一个变量:
date_pattern="[[:digit:]][[:digit:]]/[[:digit:]][[:digit:]]/[[:digit:]][[:digit:]][[:digit:]][[:digit:]]"
if [[ $1 = $date_pattern ]]; then
(在这里你不能引用右手边$date_pattern
(。