4
\$\begingroup\$

I have been working on a script that automatically checks on the state of 2 services that I require to be running 24/7 on a server that I manage.

The script works as I need, but I would really like to optimize it if possible. Specifically, I find that I want a way to reduce the need to type the command:

$(ps -ef | grep -v grep | grep zabbix_agentd | wc -l)

and

$(ps -ef | grep -v grep | grep zabbix_server | wc -l)

Any other feedback is greatly appreciated, I am new to bash scripting and trying to find the best way to get this to be as optimal as possible!

#!/bin/bash
zabbix_server="service zabbix-server"
zabbix_agent="service zabbix-agent"
logfile=/etc/scripts/zabbix/zabbix_auto_restart.log
zabbix_server_running=0
zabbix_agent_running=0
check_zabbix_agentd (){
 if (( $(ps -ef | grep -v grep | grep zabbix_agentd | wc -l) <= 0 ))
 then
 $zabbix_agent start
 echo `date` "$zabbix_agent was stopped... Restarting" >> $logfile
 echo "************************************************" >> $logfile
 #Send email to notify that the script ran
 echo "$(date) $zabbix_agent was restarted from zabbix_restart.sh" | mutt -s "Zabbix Auto-restart Script Just Ran" <admin email address>
 else
 let zabbix_agent_running=1
 fi
}
check_zabbix_server (){
 if (( $(ps -ef | grep -v grep | grep zabbix_server | wc -l) <= 0 ))
 then
 $zabbix_server start
 echo `date` "$zabbix_server was stopped... Restarting" >> $logfile
 echo "************************************************" >> $logfile
 #Send email to notify that the script ran
 echo "$(date) $zabbix_server was restarted from zabbix_restart.sh" | mutt -s "Zabbix Auto-restart Script Just Ran" <admin email address>
 else
 let zabbix_server_running=1
 fi
}
main_loop (){
 until ((zabbix_server_running == 1 && zabbix_agent_running == 1));
 do
 check_zabbix_agentd
 check_zabbix_server
 sleep 1.5
 done
}
main_loop
asked Jun 18, 2015 at 19:18
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Instead of reinventing the wheel, consider using a standard solution such as Monit. \$\endgroup\$ Commented Jun 18, 2015 at 19:27
  • 1
    \$\begingroup\$ @200_success Zabbix is my monitoring software that does the same thing as Monit. I have this script as a safeguard in-case something were to happen. \$\endgroup\$ Commented Jun 18, 2015 at 19:45
  • 1
    \$\begingroup\$ Have Zabbix and Monit monitor each other? =) \$\endgroup\$ Commented Jun 18, 2015 at 19:46
  • \$\begingroup\$ @200_success That would be interesting lol! I did download Monit and am looking at it now \$\endgroup\$ Commented Jun 18, 2015 at 19:54

1 Answer 1

3
\$\begingroup\$

As you and I both know, what follows is the answer I posted to your question at Unix and Linux. I'm not sure if this might be considered in bad taste or not - and if so, I'll happily delete it - but at the other site the question was apparently closed as a cross-post in favor of this. And so I thought - maybe it belonged? Anyway, here goes:


What you're really doing wrong is duplicating your effort - basically every hardcoded occurrence of _agent or _server appears to be completely redundant.

For example, if this is being run on a linux system, you can completely drop the grep_...() functions, and consolidate both check_...s into a single entity which might work like:

email(){ 
 mutt -s "Zabbix Auto-restart Script Just Ran" \<user email\>
}
prlog(){ 
 date +"%x %X:%tservice 1ドル${2+%n************************}"
}
chk_run()
 while [ "$#" -gt 0 ]
 do if ps -C zabbix_"1ドル"
 then : "$((1ドル=1))"
 else set zabbix_"$@"
 service "1ドル" start || eval >&2 '
 prlog "1ドル restart failed." +; exit '"$?"
 prlog "1ドル restarted." + >&2
 prlog "1ドル restarted from 0ドル." |email
 fi; shift
 done

The key to that is you would just call chk_run with an argument list each member of which would indicate to it what it should be checking each iteration.

loop()
 until [ "$((1ドル&&2ドル))" -eq 1 ]
 do chk_run "$@"
 sleep 2
 done >/dev/null 2>>"$log"
agentd=0 server=0 loop agentd server

POSIXly the only thing that should need altering there is the ps command - because POSIX doesn't specify the -C switch. And so you could just change the if line to look like:

if ps -eocomm= |
 grep -xqF zabbix_"1ドル"

Aside from mutt, service, and the ps optimization, it should all be standard command language. At least one advantage to that is the #!/bin/bash hash-bang is completely unnecessary - there is no anchor here to some shell-specific extension, and so it should work pretty much exactly the same in all shells which strive for POSIX-compliance. That means that #!/bin/dash is a very simple optimization in this case.

answered Jun 19, 2015 at 4:35
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.