我已经能够显示进度指示器,而某些进程一直运行直到完成,但是当我运行while循环时,我无法正确显示相同进度指示器的代码。例如,我在脚本内部执行此操作时执行此操作:
/bin/ping -c 10 $ipaddress > /pinglog & PID=$!
printf "["
while kill -0 $PID 2> /dev/null; do
printf "."
sleep 1
done
printf "] "
我还可以在脚本中使用sleep命令显示进度:
sleep 30 & PID=$!
printf "["
while kill -0 $PID 2> /dev/null; do
printf "."
sleep 1
done
printf "] "
这两个例子都有效,我的输出如下:
[.........................}
这些点每秒都会继续,直到命令完成,这就是我想要的。但我现在试图使用while循环获得相同的输出,我无法得到我追求的结果。这是我到目前为止所拥有的。
while [[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]] & PID=$!
printf "["
while kill -0 $PID 2> /dev/null; do
printf "."
sleep 1
done
printf "] "
do
sleep 5
done
echo $VAR1 was found
然而,当找到字符串并且输出如下所示时,它不会停止:
[.] [.] [.] [.] [.] and on and on...
我已经尝试移动实际的while循环do,sleep 5并在第一个printf语句之上完成,但结果更糟,我甚至没有获得进度指示器输出。我如何解决这个问题,以便获得与前2个示例相同的进度指示器输出,并在找到模式时停止?
答案 0 :(得分:1)
while
测试的命令是do
之前的最后一个命令。因此,您的循环基本上是while ...; printf "] "; do ... ; end
,并且由于printf
永远不会失败,while
永远不会终止。
虽然我不清楚你期望用while
循环测试什么。如果期望复合命令[[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]] &
将被测试,您应该知道当您在后台运行命令时,状态代码仅反映bash
是否能够按顺序分叉子项运行后台命令(几乎总是如此)。在命令完成之前,命令的状态代码不可用,因此如果您只想检查状态代码,它在后台运行它或多或少是毫无意义的。
如果您希望这样做,您可以对整个while
循环进行后台处理;将&
放在终止done
复合语句的while
之后。这可能就是你真正想要的东西:
printf "["
while ! grep -wqm1 "$VAR1" logfile; do
sleep 1
done &
while kill -0 $! 2>/dev/null; do
printf "."
done
printf "] "
注意:-q
的{{1}}选项会导致它只生成状态返回。 (通过该更改,grep
实际上是多余的。)这避免了必须使用-m1
来测试输出。除非您100%确定[[
不能包含空格或shell元字符,否则应使用引号括起扩展。不需要在变量中存储$VAR1
,因为它将继续包含相同的值,直到您将其他命令作为背景。
答案 1 :(得分:0)
我已经解决了这个问题。要拥有[........]输出格式,你必须启动第一个printf" ["在第一个while循环开始之前。然后将sleep 5命令放在后台并在其PID上使用第二个while循环,而不是初始while循环本身,因为我们想要杀死sleep 5命令而不是while循环本身。这将允许点每隔一秒而不是每5秒在括号内重复,并允许找到搜索字符串。最后把最后的printf"]"在搜索字符串的while循环结束后,完成格式化的最后一次完成。这可以防止每五秒重复一次[。]。这对我有用:
printf "["
while [[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]]
do
sleep 5 & PID=$!
while kill -0 $PID 2> /dev/null; do
printf "."
sleep 1
done
done
printf "] "
echo $VAR1 was found