Estou executando o script abaixo:
#!/bin/bash
ps ax | grep -q [v]arnish
if [ $? -eq 0 ];then
echo varnish is running...
exit 0
else
echo "Critical : varnish is not running "
exit 2
fi
A saída é como:
[root@server ~]# sh -x check_varnish_pro.sh
+ ps ax
+ grep -q '[v]arnish'
+ '[' 0 -eq 0 ']'
+ echo varnish is running...
varnish is running...
+ exit 0
Quando executo o mesmo na linha de comando, estou obtendo o status de saída como 1:
[root@server ~]# ps ax | grep -q [v]arnish; echo $?
1
O caso é como verniz não está instalado no servidor. Este script funciona bem em um servidor em que o verniz está instalado.
Por que status de saída diferente quando executado usando script e linha de comando? Como melhorar esse script?
shell-script
process
ps
exit-status
prado
fonte
fonte
Respostas:
Quando você executa um script chamado
check_varnish_pro.sh
testeé bem-sucedido porque existe um script chamado
check_
verniz em_pro
execução.fonte
Em geral, é uma má idéia tentar a abordagem simples
ps
egrep
determinar se um determinado processo está em execução.Você ficaria muito melhor usando
pgrep
isso:Veja o manual para
pgrep
. Em alguns sistemas (provavelmente não no Linux), você recebe um-q
sinalizador que corresponde ao mesmo sinalizador para ogrep
qual se livra da necessidade de redirecionar/dev/null
. Há também um-f
sinalizador que executa a correspondência na linha de comando completa, e não apenas no nome do processo. Pode-se também limitar a correspondência aos processos pertencentes a um usuário específico usando-u
.A instalação
pgrep
também fornece acesso aopkill
que permite sinalizar processos com base em seus nomes.Além disso, se este é um daemon de serviço , e se o seu sistema Unix tem uma maneira de consultá-lo para obter informações (por exemplo, se ele está funcionando ou não), essa é a maneira correta de verificar isso.
No Linux, você possui
systemctl
(systemctl is-active --quiet varnish
retornará 0 se estiver em execução, 3 caso contrário), no OpenBSDrcctl
, etc.Agora para o seu script:
No seu script, você analisa a saída de
ps ax
. Esta saída conterá o nome do próprio scriptcheck_varnish_pro.sh
, que obviamente contém a stringvarnish
. Isso lhe dá um falso positivo. Você teria percebido isso se o tivesse executado sem o-q
sinalizadorgrep
durante o teste.Executando:
Outro problema é que, embora você tente "ocultar" o
grep
processo de ser detectado porgrep
si mesmo usando[v]
o padrão. Essa abordagem falhará se você executar o script ou a linha de comando em um diretório que contenha um arquivo ou diretóriovarnish
(nesse caso, você receberá um falso positivo novamente). Isso ocorre porque o padrão não está entre aspas e o shell executará o nome do arquivo globbing com ele.Vejo:
A presença do arquivo
varnish
fará com que o shell seja substituído[v]arnish
pelo nome do arquivovarnish
e você receberá um hit no padrão na tabela de processos (ogrep
processo).fonte
check_varnish_pro.sh
também é um fator.O @AlexP explica muito sucintamente o que realmente está acontecendo, mas a idéia de @ Kusalananda de usar
pgrep
/pkill
para um processo crítico é fortemente desencorajada . Melhores soluções incluem:systemctl status varnishd
deve cuidar disso em uma instalação moderna * nix.Se, por alguma circunstância infeliz, você não tiver um serviço disponível, basta alterar o script de inicialização para relatar o problema assim que o processo terminar:
kill -0 "$pid"
.fonte
systemctl
quase só está disponível no Linux (AFAIK), e não em todos os sistemas modernos do tipo Unix.