1

My server always shut down when it reach a high load average. I have optimized my Apache, MySQL. But I cannot prevent sometime in a heavy traffic. So I try to write some shell to control load average.

#!/bin/bash
check=`uptime | sed 's/\./ /' | awk '{print $10}'`
if[$check -gt 5]
then
  /usr/bin/systemctl restart httpd.service
fi

but it report error when I excuse the script

/var/www/html/load_average.sh: line 3: if[0.98, -gt 5]: command not found
/var/www/html/load_average.sh: line 4: syntax error near unexpected token `then'
/var/www/html/load_average.sh: line 4: `then'

Another question, how to run the script in every 10 seconds with cronjob?

another working code, share to everyone:

#!/bin/bash
check=$(uptime | tr -d ',' | awk '{print $10}')
if [[ $check > 5 ]]; then
  /usr/bin/systemctl restart httpd.service
fi

in cronjob part

* * * * * /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 10; /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 20; /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 30; /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 40; /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 50; /var/www/html/load_average.sh >/dev/null 2>&1
2

2 Answers 2

2

You must separate the brackets from the data with spaces, like this:

for I in 0 1 2 3 4 5; do
    check=$(uptime | tr -d ',.' | awk '{print $10}')
    if [ "$check" -gt 5 ]; then
        /usr/bin/systemctl restart httpd.service
    fi
    sleep 10
done

In UNIX, [ is really a shell command. When the shell replaces the $check variable by its value, it will try to find the resulted command, hence the error. Additionally, I suggest you quoting the $check variable, as if it gets replaced by an empty string or a whitespace, it would by a syntax error.

Regarding your crontab question, execute crontab -e and add an entry like this one to your file:

* * * * * /PATH/TO/YOUR/SCRIPT

Cronjobs minimal resolution elapse time is 1 minute, so, you will have to use a loop for repeting the check 6 times every ten seconds.

8
  • still report error /var/www/html/load_average.sh: line 4: syntax error near unexpected token then' /var/www/html/load_average.sh: line 4: if[$check -gt 1]; then'. I have edit it in ssh vi commond. Feb 13, 2015 at 20:44
  • 1
    White spaces around the brackets are compulsory. You must separate the [ from the if and the $check tokens. The same for the compared value. if [ "$check" -gt 1 ]
    – Antxon
    Feb 13, 2015 at 20:47
  • now only report /var/www/html/load_average.sh: line 3: if[0.93, -gt 5]: command not found, why there has a common before ` -gt`? Feb 13, 2015 at 20:50
  • Data is still not separated from the brackets with spaces.
    – Antxon
    Feb 13, 2015 at 20:55
  • I have added brackets with spaces. Feb 13, 2015 at 20:58
0

if[0.98, -gt 5]

Bash can't do floating point arithmetic. You can do if (( 98 > 500 )) - double round parens allow arithmetic expressions and variable expanding is done in such automatically, so if (( check > 500 )) if your variable is $check. Fortunately, awk does handle basic arithmetic pretty well.

#!/bin/bash
check=$(LC_ALL=C uptime | awk '{print 100*$10 }')
if (( check > 5 ))
then
  /usr/bin/systemctl restart httpd.service
fi

Backticks are deprecated for ages, now.

However, restarting the web server, when too busy might annoy enough visitors, to push the load average down. It doesn't lock as the right solution since it increases the work. Maybe a profiler might help in finding a bottleneck.

And probably better ways to limit the load average, the web server may cause, exist from within the project - I could only give advice how to improve the shell script.

The LC_ALL setting is probably only needed on my machine, which uses a German environment by default and shows 0.83 as 0,83. But it will not be wrong either.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .