2

是否可以在脚本创建的后台作业中使用 while 循环?当我在命令提示符下手动运行它时,这工作得很好。

调用脚本内容 (test.sh)

#!/bin/bash
> switch
echo 'Running' >> switch
check=$(more switch)
echo $check 

while [ $check = 'Running' ]
do
sleep 5s    
check=$(more switch)
    echo $check  
done

调用脚本内容 (start.sh)

#!/bin/bash
$PWD/test.sh &

我收到一个错误:

-bash: [: 参数太多

当调用脚本运行时。调用的脚本手动运行没有问题。在脚本创建的后台作业中不允许使用 while 循环吗?

4

3 回答 3

2
echo 'Running' >> swtich
check=$(more switch) 

您写入一个名为的文件swtich,然后读取一个名为switch. 该文件不存在,因此变量check最终为空。

顺便说一句,为什么打电话more?这仅对逐页查看文件有用。如果您正在管道输出,cat则等效。如果more没有控制终端,当您test.sh在后台调用时会发生这种情况,会more打印一个包含文件名的额外行,因此它的输出

所以你真的必须使用cat而不是more. (在 bash 中,您也可以编写check=$(<switch).)

[ $check = 'Running' ]

由于$check为空,该命令[接收三个参数=Running]。这不是该[命令的有效语法。

始终在变量替换和命令替换周围加上双引号:"$check", "$(somecommand)". 如果$替换发生在引号之外,则结果将拆分为单独的单词(在您的情况下为 0 个单词,因为结果为空),并且这些单词被解释为文件 glob 模式。这几乎是不可取的,所以总是使用双引号,除非你真的有一个 glob 模式列表。

check=$(cat switch)实际上是安全的,因为在作业中,右侧需要一个单词,因此不会发生分词。但是,为了清楚起见,您不妨写一下check="$(cat switch)"。另外,如果你写的话,引号是必需的export check="$(cat switch)"

所以我们有:

#!/bin/bash
echo 'Running' >> switch
check=$(cat switch)

while [ "$check" = 'Running' ]
do
  sleep 5s
  check=$(cat switch)
done

在 bash 中(但不是在 sh 中),您可以编写[[ $check = Running ]]而不是[ $check = Running ]. 那是因为[[ … ]]它是特殊的语法,不像[是没有特殊解析的内置命令。但是,如果变量位于运算符的右侧,则需要双引号,因为inside=的右侧是一个模式。与其学习这么复杂的规则,只要一直使用双引号就可以了。=[[ … ]]

于 2013-09-21T11:21:25.553 回答
0

尝试这个:

nohup yourprogram >>/dev/null 2>>/dev/null &

您的程序内容不应有 & 或 nohup

于 2013-09-20T14:31:09.603 回答
0

问题基本上是您没有在 test 命令中引用参数。它应该是

while [ "$check" = 'Running' ]

在变量周围加上双引号。如果你这样做,你会注意到你在第一行有一个错字。代替

echo 'Running' >> swtich

它应该是

echo 'Running' >> switch

然后它应该按预期工作

作为旁注,最好不要使用 more 命令来读取文件的内容,因为它是为人类设计的,而只是这样做:

check=$(<switch) 
于 2013-09-21T11:16:03.023 回答