Bash脚本意外导致while循环

时间:2015-05-25 08:55:31

标签: linux bash shell scripting

我有以下bash脚本来停止Apache服务器。我没有收到错误,但结果出乎意料。

#!/bin/bash

/etc/init.d/httpd stop
if [[ $? -ne 0 ]]
then
    exit 1
fi
RTN=10
while [[ $RTN -gt 0 ]]
echo "Before" $RTN
do
    sleep 5
    RTN=`ps -C httpd | wc -l`
    RTN=$(( RTN - 1 ))
echo "After" $RTN
done 

exit 0

我得到了以下答案,我不希望这样,无限打印:

Before 10
After 0

Before 0
After 0

Before 0
After 0

我希望打印:

Before 10
After -1 
#and exit here

有人可以告诉我发生了什么事吗?

2 个答案:

答案 0 :(得分:2)

这不像您认为的那样有效:

while [[ $RTN -gt 0 ]]
echo "Before" $RTN
do

您希望echo在{/ em> do之后 。在do之前使用它,它是list-1条件的一部分而不是list-2正文。并且,根据bash文档(我的粗体):

  

只要列表while中的 last 命令返回退出,list-2命令就会继续执行列表list-1状态为零。

您可以看到以下脚本之间的区别,与您的类似:

#!/usr/bin/bash
RTN=2
while [[ $RTN -gt 0 ]]
echo "Before" $RTN
do
    sleep 1
    RTN=$(( RTN - 1 ))
echo "After" $RTN
done

输出(无限广告):

Before 2
After 1
Before 1
After 0
Before 0
After -1
Before -1
After -2
Before -2

echo移动到内部正文:

#!/usr/bin/bash
RTN=2
while [[ $RTN -gt 0 ]]
do
    echo "Before" $RTN
    sleep 1
    RTN=$(( RTN - 1 ))
    echo "After" $RTN
done

然后正确终止:

Before 2
After 1
Before 1
After 0
<returns to prompt>

完成更改后,如果您的ps命令生成了值,则循环会正确终止。

此外,如果你想找出进程列表中的内容(并且可能导致结果为零而不是负数),请在检查计数之前输出进程列表:

:
ps -C httpd                 # Add this line temporarily.
RTN=`ps -C httpd | wc -l`
:

答案 1 :(得分:1)

您的ps -C httpd命令始终返回一行:PID TTY TIME CMD(基本上是ps输出的标题),当没有进程正在运行时,wc -l计为1 。如果httpd正在运行,则行数将大于1。

因此$((RTN -1))变为0

编辑:

我注意到,你的while循环中有错误:

while [[ $RTN -gt 0 ]]
echo "Before" $RTN
do

将其更改为:

while [[ $RTN -gt 0 ]]
do
echo "Before" $RTN