Neden ps için farklı çıkış durumu alıyorum | bir senaryoda grep?


11

Komut dosyasının altında çalışıyorum:

#!/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

Çıktı şöyle:

[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

Komut satırında aynı çalıştırdığımda çıkış durumunu 1 olarak alıyorum:

[root@server ~]# ps ax  | grep -q [v]arnish; echo $?
1

Durum vernik sunucuya yüklü değil gibidir. Bu komut dosyası, verniğin yüklü olduğu bir sunucuda iyi çalışır.

Komut dosyası ve komut satırı kullanılarak çalıştırıldığında neden farklı çıkış durumu var? Bu script nasıl geliştirilir?


Bu tür bir hacker değil, gerçek bir süreç denetleme sistemi kullanın. İşletim sisteminiz, kalmak istediğiniz daemonlarınızın, start up, daemontools, systemd, launchd veya diğer birçok alternatiften biri olsun, arıza durumunda otomatik olarak yeniden başlatılmasını sağlamak için neredeyse kesinlikle yerleşik bir yol olacaktır. Hepsi bu tür elle haddelenmiş hackery'den daha sağlam ve yetenekli olacak.
Charles Duffy

Yanıtlar:


10

check_varnish_pro.shTest adlı bir komut dosyası çalıştırdığınızda

ps ax  | grep -q [v]arnish

check_vernik_pro çalışıyor adında bir komut dosyası olduğundan başarılı .


14

Genel olarak, basit bir yaklaşım denemek için kötü bir fikir psve grepbelirli bir süreç çalışıp çalışmadığını belirlemek için denemek için.

Bunun pgrepiçin kullanmak çok daha iyi olurdu :

if pgrep "varnish" >/dev/null; then
  echo "Varnish in running"
else
  echo "Varnish is not running"
fi

İçin kılavuza bakınız pgrep. Bazı sistemlerde (muhtemelen Linux'ta değil), yönlendirme gereksiniminden kurtulan -qaynı bayrağa karşılık gelen bir bayrak alırsınız . Ayrıca , işlemi yalnızca işlem adından ziyade tam komut satırında gerçekleştiren bir bayrak vardır. Ayrıca eşleşme, belirli bir kullanıcıya ait işlemlerle sınırlandırılabilir .grep/dev/null-f-u

Kurulum pgrepayrıca pkill, adlarına göre süreçleri işaretlemenize izin veren erişim sağlar.

Ayrıca, bu bir hizmet arka plan programı ise ve Unix sisteminizde bunu bilgi için sorgulamanın bir yolu varsa (örneğin, çalışıp çalışmadığını), o zaman bu kontrol etmenin uygun yoludur.

Linux'ta, sahip systemctl( systemctl is-active --quiet varnishÇalışıyorsa 3 aksi takdirde 0 döndürür), sahip OpenBSD'deki rcctlvs.


Şimdi senaryonuza:

Senaryonuzda çıktıyı ayrıştırırsınız ps ax. Bu çıktı, check_varnish_pro.shaçıkça dizeyi içeren betiğin adını içerecektir varnish. Bu size yanlış bir pozitif verir. Test sırasında -qbayrağı olmadan çalıştırsaydınız bunu fark ederdiniz grep.

#!/bin/bash
ps ax | grep '[v]arnish'

Koşu:

$ ./check_varnish_pro.sh
31004 p1  SN+     0:00.04 /bin/bash ./check_varnish_pro.sh

Başka bir sorun, desende kullanarak grepişlemin grepkendi başına algılanmasını "gizlemeye" çalışmanızdır [v]. Komut dosyasını veya komut satırını, içinde bir dosya veya dizin bulunan bir dizinde çalıştırırsanız bu yaklaşım başarısız olur varnish(bu durumda yine yanlış pozitif alırsınız). Bunun nedeni, desenin tırnaksız olması ve kabuğun onunla dosya adı globbing yapmasıdır.

Görmek:

bash-4.4$ set -x
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep '[v]arnish'
bash-4.4$ touch varnish
+ touch varnish
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep varnish
91829 p2  SN+p    0:00.02 grep varnish

Dosyanın varlığı varnishkabuğun [v]arnishdosya adıyla değiştirilmesine neden olur varnishve işlem tablosundaki ( grepişlem) desende bir isabet alırsınız .


4
çünkü her şey "linux ülkesinde" bir dosyadır.
zee

@ z_- Nasıl bağlandığından emin değilim, ancak Linux Unices'te bile bu geçerli.
Kusalananda

4
Sadece grep süreci değil; adlandırılan komut dosyası check_varnish_pro.shda bir faktördür.
TNW

@TNW İlk başta fark etmedim, ama haklısın. Bunu ekleyeceğim.
Kusalananda

3

@AlexP , gerçekte ne olduğunu çok açık bir şekilde açıklıyor , ancak @ Kusalananda'nın kritik bir süreç için / kullanmapgreppkill fikri kesinlikle önerilmez . Daha iyi çözümler şunları içerir:

  • Hizmete çalışıp çalışmadığını sorma . systemctl status varnishdmodern bir * nix kurulumunda bununla ilgilenmelidir.
  • Bazı talihsiz durumlarda, mevcut bir hizmetiniz yoksa, işlem biter bitmez sorunu bildirmek için başlangıç ​​komut dosyasını değiştirebilirsiniz:

    varnish || true
    some_command_to_send_an_alert_that_the_service_has_died
    
  • Alternatif olarak, hizmeti başlatan komut dosyasını PID'yi kaydetmek için değiştirin ve ardından durumunu düzenli aralıklarla kontrol edin kill -0 "$pid".

Katılıyorum, sadece sorunun kabuk betimleme yönlerini ele alıyordum. Bunun systemctlneredeyse tüm Linux'ta (AFAIK) mevcut olduğunu ve tüm modern Unix benzeri sistemlerde mevcut olmadığını unutmayın.
Kusalananda

Orijinal soru "linux" etiketine sahipti; Bunun neden muru tarafından kaldırıldığından emin değilim.
l0b0

Teşekkürler l0b0. "Neden" ve "Nasıl geliştirilir" şeklinde iki sorum vardı. @ AlexP'in cevabı ilk sorumu çözdü ve cevabınız ikinci soru için daha iyi bir çözüm. Ancak Kusalananda, bununla ilgili benzer sorunları olan insanlar için yararlı olacağını düşündüğüm şeyleri açıklıyor. Şimdi kafam karıştı ki cevap olarak kabul edeceğim.
prado

@prado Sizin için
l0b0
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.