Uruchomiam poniżej skryptu:
#!/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
Dane wyjściowe są jak:
[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
Kiedy uruchamiam to samo w wierszu poleceń, otrzymuję status wyjścia jako 1:
[root@server ~]# ps ax | grep -q [v]arnish; echo $?
1
Sprawa jest taka, jakby lakier nie został zainstalowany na serwerze. Ten skrypt działa dobrze na serwerze, na którym zainstalowany jest lakier.
Po co różny status wyjścia, gdy jest uruchamiany za pomocą skryptu i wiersza poleceń? Jak ulepszyć ten skrypt?
shell-script
process
ps
exit-status
prado
źródło
źródło
Odpowiedzi:
Po uruchomieniu skryptu o nazwie
check_varnish_pro.sh
testodnosi sukces, ponieważ działa skrypt o nazwie
check_
lakier_pro
.źródło
Ogólnie rzecz biorąc, złym pomysłem jest wypróbowanie prostego podejścia
ps
igrep
próba ustalenia, czy dany proces działa.Lepiej byłoby użyć
pgrep
do tego:Zobacz instrukcję dla
pgrep
. W niektórych systemach (prawdopodobnie nie w Linuksie) otrzymujesz-q
flagę odpowiadającą tej samej fladze, dlagrep
której pozbywasz się potrzeby przekierowywania/dev/null
. Istnieje również-f
flaga, która wykonuje dopasowanie w pełnym wierszu poleceń, a nie tylko w nazwie procesu. Można również ograniczyć dopasowanie do procesów należących do konkretnego użytkownika-u
.Instalowanie
pgrep
daje również dostęp do tego,pkill
co pozwala sygnalizować procesy na podstawie ich nazw.Ponadto, jeśli jest to demon usługi i jeśli twój system uniksowy ma sposób na zapytanie go o informacje (np. Czy jest uruchomiony, czy nie), to jest to właściwy sposób sprawdzania go.
W systemie Linux masz
systemctl
(systemctl is-active --quiet varnish
zwróci 0, jeśli jest uruchomiony, 3 w przeciwnym razie), w OpenBSD maszrcctl
itp.Teraz do skryptu:
W skrypcie analizujesz dane wyjściowe z
ps ax
. Dane wyjściowe będą zawierać nazwę samego skryptucheck_varnish_pro.sh
, który oczywiście zawiera ciągvarnish
. To daje fałszywie pozytywny wynik. Zauważyłbyś to, gdybyś testował go bez-q
flagigrep
.Uruchamianie:
Innym problemem jest to, że chociaż próbujesz „ukryć” sam
grep
proces przed wykryciemgrep
za pomocą[v]
wzorca. Takie podejście zakończy się niepowodzeniem, jeśli zdarzy się, że uruchomisz skrypt lub wiersz poleceń w katalogu, w którym znajduje się nazwa pliku lub kataloguvarnish
(w takim przypadku ponownie otrzymasz fałszywy wynik dodatni). Wynika to z faktu, że wzorzec nie jest cytowany, a powłoka będzie wykonywać z nim globbing nazw plików.Widzieć:
Obecność pliku
varnish
spowoduje, że powłoka zastąpi[v]arnish
nazwę plikuvarnish
i otrzymasz trafienie we wzorzec w tabeli procesów (grep
proces).źródło
check_varnish_pro.sh
jest również czynnikiem.@AlexP wyjaśnia bardzo krótko, co się rzeczywiście dzieje, ale @ idei Kusalananda dnia używając
pgrep
/pkill
krytycznego procesu jest zdecydowanie odradzane . Lepsze rozwiązania obejmują:systemctl status varnishd
powinien się tym zająć w nowoczesnej instalacji * nix.Jeśli z jakiegoś niefortunnego powodu nie masz dostępnej usługi, możesz po prostu zmienić skrypt startowy, aby zgłosić problem, gdy tylko proces się zakończy:
kill -0 "$pid"
.źródło
systemctl
jest prawie dostępna tylko w systemie Linux (AFAIK), a nie we wszystkich nowoczesnych systemach uniksowych.