4

我正在尝试编写一个 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 `]'

如果有人能指出我正确的方向。

4

4 回答 4

5

这是了解您的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'
  • 有两个单独的大于测试运算符用于比较。一种用于字符串,一种用于整数。-gt是对整数的测试。由于您正在处理字符串,因此您需要使用>

    而测试 "$(date +"%T")" > '06:00:00' -a "$(date +"%T")" < '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' ]]
于 2013-06-05T01:26:20.513 回答
2

你不能像那样比较整个小时。

当您只是检查小时 (6<=x<=21) 时,请使用date "+%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 推荐方式是:

if [ -f $VAR1 ] && [ -f $VAR2 ] && [ -f $VAR3 ]
于 2013-06-04T21:58:58.690 回答
1

看起来你只关心时间,所以:

#!/bin/bash

while [ $(date +"%k") -gt 6 -a $(date +"%k") -lt 21 ];
do
  ##echo `php mainstatquery.php`
  echo "Hello World";
  sleep 5;
done
于 2013-06-04T22:09:31.950 回答
0

]关闭命令的必须[是单独的参数。在它前面放一个空格。

于 2013-06-04T21:57:32.880 回答