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

Я работаю над скриптом, который можно использовать для автоматического перезапуска моих служб мониторинга 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-скриптом при запуске с панели запуска
  • Разделить вход для другой команды и объединить результат
  • tr -c '' '\ n' не заменяет всех символов дополнения
  • Избавиться от символов 000A в именах файлов
  • Как я могу вызвать событие в сценарии оболочки при удалении USB-устройства?
  • запрос повторно выполняется для сценариев цикла параллельно
  • Как явно загружать интерпретатор оболочки в программу C
  • grep и умножить определенные столбцы
  • Переименование и переупорядочение нескольких имен файлов без переименования
  • не может скопировать более 29 файлов на целевой сервер, используя сценарий оболочки
  • Как использовать аргументы, такие как $ 1 $ 2 ... в цикле for?
  • Interesting Posts

    Попытка создания (a) пакета kmod для acpi_call на Fedora, не может быть установлена

    Печать значения столбца в следующей строке

    Перемещение Xen DomU на новое блочное устройство

    Захват многострочного вывода встроенного bash

    Когда параллельный выход GNU, моя программа также терпит неудачу

    Нечетное неправильное поведение пароля с помощью GRUB cryptodisk

    Команда тайм-аута «время» в bash

    Может ли apt обновлять установленные вручную пакеты

    Настольные уведомления о завершенных задачах

    Vimrc, управление картой; к действию

    Не могу подключиться через ssh, используя технику без пароля, к centos 7 как пользователь, но как root успешно

    Различия между зарезервированным словом и командой `time` на встроенной оболочке оболочки, функции, конвейере и списке команд?

    Резервное копирование на диск Amazon Cloud

    Исправление соответствия шаблонов для сценария оболочки

    Выполнение потенциально вредной программы на Linux

    Linux и Unix - лучшая ОС в мире.