Bir hizmetin komut dosyasında çalışıp çalışmadığını test etmenin "uygun" yolu


96

Benim sorunum:

Bir bash betiği yazıyorum ve içinde belirli bir hizmetin çalışıp çalışmadığını kontrol etmek istiyorum.

Bunu el ile nasıl yapacağımı biliyorum $ service [service_name] status.

Ancak (özellikle sisteme geçtikten sonra) ayrıştırılması biraz dağınık olan bir sürü metni basar. Basit çıktıya sahip komut dosyaları için yapılmış bir komut veya kontrol edebileceğim bir dönüş değeri olduğunu varsaydım.

Ancak Googling, yalnızca bir ton “Oh, sadece ps aux | grep -v grep | grep [service_name]” sonuç verir. Bu en iyi uygulama olamaz, değil mi? Ya bu komutun başka bir örneği çalışıyorsa, ancak SysV init betiği tarafından başlatılmadıysa?

Yoksa çenemi kapatıp ellerimi küçük bir pgrep ile kirletmeli miyim?

Yanıtlar:


139

systemctlBunun için bir is-activealt komut var:

systemctl is-active --quiet service

serviceaktifse sıfır durumuyla çıkacaktır , aksi takdirde sıfır değildir, komut dosyaları için idealdir:

systemctl is-active --quiet service && echo Service is running

Bunu atlarsanız --quiet, mevcut durumu standart çıktısına da verir.

Don_crissti tarafından belirtildiği gibi , hizmeti sağlamak için hiçbir şey yapılmasa da bazı birimler aktif olabilir: “RemainAfterExit” olarak işaretlenmiş birimler, başarılı bir şekilde çıkmaları durumunda aktif olarak kabul edilir, servise ihtiyaç duymayan bir hizmet verdikleri fikri ( örneğin , sistemin bir yönünü yapılandırırlar). Daemon'ları içeren birimler, ancak daemon hala çalışıyorsa aktif olacaktır.


Kış servislerine dikkat et. Bunlar sadece inactiveveya activatingher iki systemctl statusve systemctl is-active(itibarıyla çıkış 3 ile systemd-241 Geçici):systemctl show service | grep -qx ActiveStatus=activating
Alois Mahdal

@Alois Aktif olan bir hizmet servisini düşünmek istediğiniz yerlerde ne tür senaryolarla karşılaştığınızı merak ediyorum; bir örnek var mı
Stephen Kitt

Tabii, @StephenKitt. Araç foo, sisteme yeniden başlatmayı içeren bir şey yapar ve bir foo_cleanupsonraki seferde işleri temizlemek için tek seferlik bir servis kullanır . Ben ve sonradan hatalarını toplamak istediğiniz bu (aynı zamanda bir hizmet olarak planlanmıştır senaryomu) test, ama ne zaman kulüpler olduğunu sonradan (Vsauce müzik)? Kriterlerden biri de foo_cleanupbunun bitmiş olmasıdır ("aktif olmayı bıraktı").
Alois Mahdal

'Başarısız' seçeneğinin de bir seçenek olduğunu belirtmek faydalı olabilir ve başlatılmayan bir servisi temel alan bir işlem yapmanız gerekirse kullanışlıdır.
Phill Healey

33

systemctlkomut dosyası için uygun bir moda sahip; showyerine kullanın statusve yalnızca istediğiniz çıktıyı elde etmek için -p/ --propertiesve --valueseçeneklerini ekleyin .

İşte bir örnek (bir Ubuntu 17.04 sisteminden):

$ systemctl show -p SubState --value NetworkManager
running

Koşmak (ya da başka şekilde) a SubState. Bir servisin aktif olup olmadığını bilmek istiyorsanız, özelliği kullanın.ActiveState

$ systemctl show -p ActiveState --value x11-common
inactive
$ systemctl show -p SubState --value x11-common
dead

Notlardan man:

show [PATTERN...|JOB...]
           Show properties of one or more units, jobs, or the manager
           itself. If no argument is specified, properties of the
           manager will be shown. If a unit name is specified, properties
           of the unit are shown, and if a job ID is specified,
           properties of the job are shown. By default, empty properties
           are suppressed. Use --all to show those too. To select specific
           properties to show, use --property=. This command is intended
           to be used whenever computer-parsable output is required. Use
           status if you are looking for formatted human-readable output.

-p, --property=
           When showing unit/job/manager properties with the show command,
           limit display to properties specified in the argument. The
           argument should be a comma-separated list of property names,
           such as "MainPID". Unless specified, all known properties are
           shown. If specified more than once, all properties with the
           specified names are shown. Shell completion is implemented for
           property names.

--value
           When printing properties with show, only print the value, and
           skip the property name and "=".

2
Karmaşık cevap için +1. --versionsystemctl ile seçeneği kabul edecek dağıtımları lütfen belirtin .
SK Venkat

11

Zanna'nın cevabının bir tamamlayıcısı olarak, --valueseçenek systemd'in 230 versiyonuylasystemctl show tanıtıldı . Bu yüzden debian jessie gibi bazı dağıtımlarda mevcut olmayabilir.

Bu durumda, seçenek sed'i kullanarak öykünebilir:

$ systemctl show -p ActiveState sshd | sed 's/ActiveState=//g'
active
$ systemctl show -p SubState sshd | sed 's/SubState=//g'  
running

1
+1 için işe yaramayacak - değer intro sürümü & dağıtımı belirtildi.
SK Venkat

3

Bunu komut satırı yürütme için veya komut dosyası yapıyorsanız yararlı buluyorum.

@StephenKitt tarafından kopyalandı

Bu, servisin kapalı olup olmadığını kontrol eder ve servisi yeniden başlatır.

systemctl is-active --quiet <service name> || <service name> restart

||systemctl dönüş değeri yazar tarafından açıklandığı gibi aktif değilse sıfırdan farklı anlam ise orada denetler.


Yeniden başlatmanın gerekip gerekmediğini test etmek için `is fail fail'i de kullanabilirsiniz. Başarısız bir hizmeti yeniden başlatmak için biraz daha sezgisel görünüyor.
Phill Healey

evet, ama benim için .. kendime pratik yapmak ve olmadığı zaman her şeyin çalıştığını farz etmek istedim. böylece bazı şeyleri onunla doğrulayabilirim. sadece çalışıp çalışmadığını kontrol etmek istiyorsanız, 'başarısız oldu' doğru bir seçimdir. :)
yıldız

3


Partiye çok geç kaldım, ancak systemctl komutunu kullanmak hem etkin &&hem ||de senaryoda bu şekilde etkin olmayacak. Aşağıda, tomcat için kullandığım bir tane var, ancak argüman alma yönteminde kullanabilir ve eğer birden fazla hizmeti kontrol etmek zorunda kalırsanız bunun kapsamı dışında kalması durumunda servis adını argüman olarak iletebilirsiniz.

STATUS=`systemctl is-active tomcat.service`
  if [[ ${STATUS} == 'active' ]]; then
    echo "Execute your tasks ....."
  else 
    echo " Service not running.... so exiting "  
    exit 1  
  fi

Bu nasıl kullandım .... Sadece benim paylaşıyor.

Sadelik ve kolaylıklar için burada açıklananları takip edin:

systemctl -q is-active tomcat.service  && echo "Tomcat Runnung" || echo "Service is not running at all "

Bu basitçe daha iyi nasıl if systemctl is-active --quiet tomcat.service? Ayrıca, [[standart kabuk değil.
Toby Speight

@TobySpeight Gönderimde "Gönderim şekli bu şekilde kullanıldı ... Sadece benimkini paylaşıyor." Asla söylemedim, standart bir kabuk kullanımı, eğer onu tek bir dirsek haline getirirseniz, o zaman burada olacak, ancak bu kapsam dışı olacak. Üstelik aşağıda &&ve kullanarak tek satır kullanımı kolay söz ||.
SAGAR Nair

2

Oxmel'in cevabındaki gibi sed komutunu kullanmak yerine, cut -d'=' -f 2sorgulanan her türlü özellik için kullanmak yeterlidir :

Örneğin:

$ systemctl show -p ActiveState sshd | cut -d'=' -f2
active
$ systemctl show -p SubState sshd | cut -d'=' -f2
running

Bu harika, ama bu komutların ne yaptığına dair bir açıklama yapmalısın.
Phill Healey

-1

Sadece bu harika küçük senaryoyu bulduk:

#!/bin/bash
service=replace_me_with_a_valid_service

if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
then
  echo "$service is running!!!"
else
  /etc/init.d/$service start
fi

Kaynak


Tüm servisler aynı isimdeki bir yürütülebilir dosyaya sahip değildir ve herhangi bir kullanıcı yanlışlıkla eşleşen bir komut çalıştırıyor olabilir - bu felaket için bir reçetedir.
Toby Speight
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.