Улучшение производительности скрипта

Я работаю над скриптом, который можно использовать для автоматического перезапуска моих служб мониторинга Zabbix в случае их прекращения работы. У меня сценарий работает нормально, но понял, что его можно улучшить (поскольку я новичок в создании сценариев).

Моя самая большая проблема заключалась в том, что я слишком много занимаюсь здесь или могу лучше организовать его.

#!/bin/bash zabbix_server="service zabbix-server" zabbix_agent="service zabbix-agent" logfile=zabbix_auto_restart.log logfilePath=/etc/scripts/zabbix/$logfile zabbix_server_running=0 zabbix_agent_running=0 grep_agent (){ local retval=$(ps -ef | grep -v grep | grep zabbix_agentd | wc -l) echo $retval } grep_server (){ local retval=$(ps -ef | grep -v grep | grep zabbix_server | wc -l) echo $retval } check_zabbix_agentd (){ if (( $(grep_agent) == 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" <user email> else let zabbix_agent_running=1 fi } check_zabbix_server (){ if (( $(grep_server) == 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" <user email> 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 

One Solution collect form web for “Улучшение производительности скрипта”

То, что вы на самом деле делаете неправильно, дублирует ваши усилия – в основном, любое жестко _agent появление _agent или _server оказывается полностью избыточным.

Например, если это выполняется в Linux-системе, вы можете полностью отказаться от функций grep_...() и объединить оба check_... s в единый объект, который может работать следующим образом:

 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 по 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 

Ключом к этому является то, что вы просто вызываете chk_run с списком аргументов, каждый член которого указывает на то, что он должен проверять каждую итерацию.

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

POSIXly единственное, что нужно изменить, – это команда ps потому что POSIX не указывает ключ -C . И поэтому вы можете просто изменить строку if чтобы выглядеть так:

 if ps -eocomm= | grep -xqF zabbix_"$1" 

Помимо mutt , service и оптимизации ps , это должен быть стандартный командный язык.

По крайней мере одно преимущество стандартного синтаксиса – это бесполезное хэш-событие #!/bin/bash – здесь нет привязки к некоторому расширению оболочки, и поэтому он должен работать практически точно так же во всех оболочках, которые стремятся POSIX-соответствие. Это означает, что #!/bin/dash – это очень простая (и, вероятно, эффективная) оптимизация в этом случае.

Конечно, оптимизированный или нет, этот скрипт почти всегда будет sleep .

Я отказался определять $log – в основном потому, что нечего было сказать о том, как вы его определили – все в порядке, но вы можете отказаться от определения его. Если вы можете быть уверены в вызывающей среде сценария, то это может сделать очень простой способ передачи параметров. Я имею в виду, что если скрипт вызывается ./script и уже был выполнен исполняемым, то …

 log=/dev/tty ./script 

… установит значение для $log в среде ./script при его вызове.

Я использую /dev/tty в качестве примера outfile, потому что я думаю, вы должны начать с этого, настраивая его для вашего удовлетворения. Если кодовые блоки здесь помещаются в ./script и запускаются, как описано выше, он будет записывать в реальном времени на ваш терминал, а не в какой-либо внешний файл, – и поэтому вы можете получить довольно четкую идею о том, что произойдет в вашем реальный файл журнала, когда вы в конечном итоге называете это:

 log=./real/logfile ./script 

В качестве альтернативы, как нечто вроде гибридного поведения, вы можете изменить сценарий так, чтобы там, где он говорит 2>>"$log" он говорит вместо этого:

 2>>"${log:-/hardcoded/default/path/to/logfile}" 

… в этом случае оболочка будет использовать только жестко заданное значение для $log если оно еще не определено. Это означает, что любой из:

 export log=/dev/tty; ./script log=/dev/tty ./script 

… все равно будет записывать файл журнала на терминал, и любой из …

 log= ./script unset log; ./script 

… будет записывать его на жесткий путь и …

 ./script 

… будет записываться либо на жесткий путь, либо в другое место в зависимости от того, существует ли уже ненулевое значение для $log экспортированного в среду текущей оболочки.

  • Проблема с двойными кавычками в сценарии bash
  • Bash для обнаружения системы контроля версий путем проверки статуса возврата команды
  • автоматизировать построение gnuplot с помощью bash
  • Как найти слово и удалить его со следующей строкой
  • Измените исполняемую ссылку для значка приложения в запуске GNOME 3
  • Как найти строки, содержащие более 100 символов, и содержит «if»?
  • добавить новую строку в файл с разделителями
  • Получать значения по блоку в одном файле
  • grep переменная в выражении if
  • Переменная как команда; eval vs bash -c
  • Список писем по темам
  • Задача Cron для удаления файлов старше 3 дней
  • Linux и Unix - лучшая ОС в мире.