O que você está realmente fazendo errado é duplicar seu esforço - basicamente, todas as ocorrências codificadas de _agent
ou _server
parecem ser completamente redundantes.
Por exemplo, se estiver sendo executado em um sistema linux, você pode descartar completamente as funções grep_...()
e consolidar as duas check_...
s em uma única entidade que funcione como:
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
A chave para isso é que você só chamaria chk_run
com uma lista de argumentos, cada membro do qual indicaria o que deveria estar verificando cada iteração.
loop()
until [ "$(($1&&$2))" -eq 1 ]
do chk_run "$@"
sleep 2
done >/dev/null 2>>"$log"
agentd=0 server=0 loop agentd server
POSIXly, a única coisa que deve ser alterada é o comando ps
- porque POSIX não especifica a opção -C
. E assim você poderia apenas alterar a linha if
para se parecer com:
if ps -eocomm= |
grep -xqF zabbix_"$1"
Além de mutt
, service
e ps
otimização, tudo deve ser uma linguagem de comando padrão.
Pelo menos uma vantagem da sintaxe padrão é que o #!/bin/bash
hash-bang é completamente desnecessário - não há âncora aqui para alguma extensão específica do shell e, portanto, deve funcionar exatamente da mesma maneira em todos os shells que buscam Conformidade com POSIX. Isso significa que #!/bin/dash
é uma otimização muito simples (e provavelmente eficaz) nesse caso.
Claro, otimizado ou não, esse script quase sempre será sleep
.
Recusei-me a definir $log
- principalmente porque não havia nada a dizer sobre o modo como você o definiu - tudo bem - mas você pode querer deixar de defini-lo. Se você puder ter certeza do ambiente de chamada do script, ele poderá criar um meio muito simples de passar parâmetros. O que quero dizer é que, se o script é chamado ./script
e já foi feito executável, então ...
log=/dev/tty ./script
... definirá o valor para $log
no ambiente de ./script
quando for chamado.
Eu uso /dev/tty
como um arquivo de exemplo porque acho que você deve começar com isso enquanto ajusta a sua satisfação. Se os blocos de código aqui forem colocados em ./script
e forem lançados como descrito acima, eles serão gravados em tempo real no seu terminal, em vez de em algum arquivo de saída - e assim você poderá ter uma ideia bem clara sobre o que acabará em seu logfile real quando você eventualmente o chama como:
log=./real/logfile ./script
Como alternativa, como algo como um comportamento híbrido, você pode alterar o script de modo que diga " 2>>"$log"
":
2>>"${log:-/hardcoded/default/path/to/logfile}"
... nesse caso, o shell usará apenas o valor codificado para $log
, se ainda não estiver definido. Isso significa que qualquer um de:
export log=/dev/tty; ./script
log=/dev/tty ./script
... ainda vai escrever o arquivo de log no terminal, e qualquer um dos ...
log= ./script
unset log; ./script
... gravará no caminho codificado e ...
./script
... grava no caminho codificado ou em algum outro local, dependendo se já existe um valor não nulo para $log
exportado para o ambiente atual do shell.