这是了解您的while
问题的简单方法:
这[
是一个实际的 Unix 命令。做ls /bin/[
,你会看到。这是/bin/test
命令的链接。man test
从命令行执行 a并查看可以完成的各种测试。
它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
.
这会给你:
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' ]]