我有以下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
有人可以告诉我发生了什么事吗?
答案 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