I have following bash script to stop Apache server. I am not getting error but an unexpected result.
#!/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
I got the following answer which I do not expect to be, with an infinite printing:
Before 10 After 0 Before 0 After 0 Before 0 After 0
I expect to print:
Before 10 After -1 #and exit here
Could anybody please tell me what is happening?
Advertisement
Answer
This doesn’t work the way you seem to think it does:
while [[ $RTN -gt 0 ]] echo "Before" $RTN do
You want the echo
to come after the do
. With it before the do
, it’s part of the list-1
condition rather than the list-2
body. And, as per the bash
docs (my bold):
The
while
command continuously executes the listlist-2
as long as the last command in the listlist-1
returns an exit status of zero.
You can see the difference between the following script, similar to yours:
#!/usr/bin/bash RTN=2 while [[ $RTN -gt 0 ]] echo "Before" $RTN do sleep 1 RTN=$(( RTN - 1 )) echo "After" $RTN done
which outputs (ad infinitum):
Before 2 After 1 Before 1 After 0 Before 0 After -1 Before -1 After -2 Before -2
When you move the echo
to inside the body:
#!/usr/bin/bash RTN=2 while [[ $RTN -gt 0 ]] do echo "Before" $RTN sleep 1 RTN=$(( RTN - 1 )) echo "After" $RTN done
it then terminates properly:
Before 2 After 1 Before 1 After 0 <returns to prompt>
Once that change is made, the loop terminates correctly, given the values being generated by your ps
command.
Additionally, if you want to find out what’s in the process list (and probably causing an result of zero rather than negative one), output the process list before checking the count:
: ps -C httpd # Add this line temporarily. RTN=`ps -C httpd | wc -l` :