两次之间的 Bash while 循环
Posted
技术标签:
【中文标题】两次之间的 Bash while 循环【英文标题】:Bash while loop between two times 【发布时间】:2013-06-04 21:52:45 【问题描述】:我正在尝试编写一个 bash 脚本,如果时间在某个时间之后和某个时间之前,它将循环。这是我得到的,但它给了我一个错误;
#!/bin/bash
while [ date +"%T" -gt '06:00:00' && date +"%T" -lt '21:00:00'];
do
##echo `php mainstatquery.php`
echo "Hello World";
sleep 5;
done
这是错误
./timer.sh: line 3: [: missing `]'
如果有人能指出我正确的方向。
【问题讨论】:
【参考方案1】:这是了解您的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'
有两个单独的大于测试运算符用于比较。一种用于字符串,一种用于整数。 -gt
是对整数的测试。既然是处理字符串,就需要使用>
:
同时测试 "$(date +"%T")" > '06:00:00' -a "$(date +"%T")"
作为替代方案,您也可以使用&&
连词而不是-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' ]]
【讨论】:
【参考方案2】:你不能像那样比较整个小时。
由于您只是检查小时 (6date "+%H" 来执行此操作:
while [ $(date +"%H") -gt 06 ] && [ $(date +"%H") -lt 21 ];
do
##echo `php mainstatquery.php`
echo "Hello World";
sleep 5;
done
还要考虑到date
表达式必须用$()
调用才能得到结果。还有你的
while [ date +"%T" -gt '06:00:00' && date +"%T" -lt '21:00:00'];
$( ) ] && [ $( ) ^ need space
最后,逻辑条件写得不好。最好的POSIX recommended方式是:
if [ -f $VAR1 ] && [ -f $VAR2 ] && [ -f $VAR3 ]
【讨论】:
任意时间的字符串比较应该可以正常工作,只要它们采用%T
格式,并且在一位数小时前添加前导零。
它没有。如果您尝试正确放置 OP 代码 while [ $(date +"%T") -gt "06:00:00" ] && [ $(date +"%T") -lt "21:00:00" ];
,您将得到 ./a: line 3: [: 00:12:27: integer expression expected
你当然是对的......我受到原始代码的影响,将-lt
视为字符串比较,但事实并非如此。如果你想比较%T
,你需要像[[ $(date +%T) > 06:00:00 ]]
这样不那么便携的东西
好点!我不认为它会起作用:$ if [[ $(date +%T) < 06:00:00 ]]; then echo yes; fi yes
。如此有趣的行为,很高兴知道@WumpusQ.Wumbley【参考方案3】:
看起来你只关心时间所以:
#!/bin/bash
while [ $(date +"%k") -gt 6 -a $(date +"%k") -lt 21 ];
do
##echo `php mainstatquery.php`
echo "Hello World";
sleep 5;
done
【讨论】:
【参考方案4】:关闭[
命令的]
必须是单独的参数。在它前面加一个空格。
【讨论】:
以上是关于两次之间的 Bash while 循环的主要内容,如果未能解决你的问题,请参考以下文章