这是了解您的while 问题的简单方法:
[ 是一个实际的 Unix 命令。做ls /bin/[,你会看到的。这是/bin/test 命令的链接。从命令行执行man test 并查看可以完成的各种测试。
while 所做的是执行你给它的命令,如果它返回零退出状态,while 语句被认为是真的,语句将继续。你可以这样做:
while sleep 2
do
echo "I slept for two seconds"
done
test 命令所做的只是进行某种测试(文件测试、相等性测试等),如果语句为真则返回零,否则返回非零:
$ test 2 -gt 3
$ echo $?
1 <- That statement is false
$ [ 2 -lt 3 ] #The test command using square brackets
$ echo $?
0 <- That statement is true.
查看test 的联机帮助页,您会看到所有有效的测试。这个:
while [ date +"%T" -gt '06:00:00' && date +"%T" -lt '21:00:00']
与
相同
while test date +"%T" -gt '06:00:00' && date +"%T" -lt '21:00:00'
让我们在这里做一些事情:
- date + %T 不是
test 命令的有效运算符。
test 命令无法在内部执行命令。您需要做的是将该命令放在$(..) 中,并可能使用引号来保证安全。因此:
while test "$(date +"%T")" -gt '06:00:00' && "$(date +"%T")" -lt '21:00:00'
-
&& 不是test 命令中的有效运算符。您可能想要的是-a,它是将test 中的两个测试串在一起的and 连词。
这会给你:
while test $(date +"%T") -gt '06:00:00' -a "$(date +"%T")" -lt '21:00:00'
作为替代方案,您也可以使用&& 连词而不是-a,但&& 的每一侧都必须是单独的测试语句:
while test "$(date +"%T")" > '06:00:00' && test "$(date +"%T")" < '21:00:00'
现在,让我们将 test 语法转换回 [...],因为它更容易理解
while [ "$(date +"%T")" > '06:00:00' -a "$(date +"%T")" < '21:00:00' ]
或
while [ "$(date +"%T")" > '06:00:00' ] && [ "$(date +"%T")" < '21:00:00' ]
顺便说一下,内部的[[...]] 更好——尤其是带有> 符号,因为它可以被shell 解释为文件重定向。
while [[ "$(date +"%T")" > '06:00:00' -a "$(date +"%T")" < '21:00:00' ]]
或
while [[ "$(date +"%T")" > '06:00:00' ]] && [[ "$(date +"%T")" < '21:00:00' ]]