在脚本创建的后台进程中运行脚本(带有while循环)时出错

时间:2013-09-20 12:55:49

标签: bash

是否可以在脚本创建的后台作业中使用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循环不允许在脚本中创建后台作业吗?

3 个答案:

答案 0 :(得分: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 ]。那是因为[[ … ]]是特殊语法,不像[,它是一个没有特殊解析的内置命令。但是,如果变量位于=运算符的右侧,则需要双引号,因为=内的[[ … ]]的右侧是模式。不是学习如此复杂的规则,而是一直使用双引号,你会没事的。

答案 1 :(得分:0)

试试这个:

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

您的节目内容不应该包含&amp;或nohup

答案 2 :(得分:0)

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

while [ "$check" = 'Running' ]

在变量周围加上双引号。如果你这样做,你会注意到你在第一行有一个拼写错误。而不是

echo 'Running' >> swtich

应该是

echo 'Running' >> switch

然后它应该按预期工作

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

check=$(<switch)