Bir işlemin çalışıp çalışmadığını ve koşullu bir kabuk betiği yapmak için nasıl kullanıp kullanmayacağı nasıl belirlenir?


108

Bir işlemin çalışıp çalışmadığını ve ardından bir bash betiğinin bu koşula dayanarak bazı şeyler yürütmesini nasıl sağlayabilirim?

Örneğin:

  • işlem abcçalışıyorsa, bunu yapın

  • çalışmıyorsa, bunu yap.


1
Aşağıdaki çözümlerden hiçbirinin işlemin durumunu dikkate almadığını not etmek önemlidir. Sorularımdan biriyle ilgili bir yorum beni buraya getirdi, ancak bununla ilgili bir cevap , beni zombiesürecin farklı programlarının durumuna getirdi ("çalışan" bir süreç olarak tanımlayacağım şey değil). Ne tam listesi STATsütun değerleri, çıktısında ps, işaret eder burada bu barındırmaktadır bir cevap yazmak veya kendi düzenlemek için eğimli olanlar için.
user66001


Süreci kontrol etmenin en iyi yolu var: stackoverflow.com/questions/3043978/…
Trevor Boyd Smith

Yanıtlar:


166

Böyle bir şeyi yapmak için bir bash betiği şuna benzer:

#!/bin/bash

# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern. 

if pgrep -x "gedit" > /dev/null
then
    echo "Running"
else
    echo "Stopped"
fi

Bu script sadece "gedit" programının çalışıp çalışmadığını kontrol ediyor.

Veya yalnızca programın bu şekilde çalışıp çalışmadığını kontrol edebilirsiniz:

if ! pgrep -x "gedit" > /dev/null
then
    echo "Stopped"
fi

@DreadPirateShawn neden / dev / null kullanıp niçin sadece 0 değil? Numarayı kullanmak, kodu en azından bir noob için (örneğin benim gibi) daha okunaklı hale getirir. Yönlendirme yok, hiçbir şey yok
Silviu

2
@ Silviu ha? Googling /dev/null: "/ dev / null komut standardı çıktısını, kendisine yazılan bilgiyi ayıran özel bir aygıt olan boş aygıta 0yönlendirir " ... komutunu kullanarak komut çıktısını bir dosyaya yönlendirir 0. Bu durumda, daha rahat > /dev/nullolmanızı öneririm - çıktıları atmanın standart / uygun yolu olduğu için her yerde görürsünüz.
DreadPirateShawn

Çok teşekkürler, bunu bir programın çalışmasından önce çalışıp çalışmadığını kontrol eden küçük bir senaryo için kullandım. (google
chrome'un

3
Lütfen -xparametreyi pgreptam uygulamayı araştıracak şekilde ekleyin, aksi takdirde başka bir uygulamanın adı içinde aynı dizgiyi bulursa yanlış bir düzeltme alır. Bunu bulmak için sadece 1 saatimi harcadım.
Thanos Apostolou

1
Programın çalışıp çalışmadığını kontrol etmek için! pgrep
Mohammed Noureldin

36

Gibi bir şey kullanan ps aux | grep abcveya pgrep abckusurlu herhangi bir çözüm .

Neden?

Belirli bir işlemin çalışıp çalışmadığını kontrol etmediğiniz için, eşleşecek olan herhangi bir işlem olup olmadığını kontrol ediyorsunuz abc. Herhangi bir kullanıcı, testinizde yanlış bir pozitif sonuç abcverecek şekilde (veya adında abcveya bağımsız değişkenlerinde bir yerde bulunan) bir yürütülebilir dosyayı kolayca oluşturabilir ve çalıştırabilir . Orada uygulayabileceğiniz çeşitli seçenekler vardır ps, grepve pgreparamayı daraltmak için, ama yine de güvenilir bir testi alamayacak.

Peki, belirli bir çalışan işlem için nasıl güvenilir bir şekilde test edebilirim?

Bu, test için neye ihtiyacın olduğuna bağlı.

Abc servisinin çalıştığından emin olmak istiyorum , değilse

Bu init ve starttart içindir. Hizmete başlayacaklar ve para iadelerinin bir ihale dosyasında saklanmasını sağlayacaklar. Hizmeti yeniden başlatmayı deneyin (init veya upstart yoluyla), pidfile'i kontrol eder ve orada değilse başlatın veya zaten çalışıyorsa iptal edin. Bu hala% 100 güvenilir değil, ancak aldığınız kadar yakın.

Bkz benim oyun sunucusu hala çalışıyorsa ... görmek için kontrol nasıl başka çözümlere.

abc benim senaryom. Komut dosyamın yalnızca bir örneğinin çalıştığından emin olmam gerekiyor.

Bu durumda, bir lockfile veya lockdir kullanın. Örneğin

#!/usr/bin/env bash

if ! mkdir /tmp/abc.lock; then
    printf "Failed to acquire lock.\n" >&2
    exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT  # remove the lockdir on exit

# rest of script ...

Diğer kilitleme yolları için Bash SSS 45'e bakınız .


3
Bu teknik olarak doğru olsa da, gerçek hayatta böyle bir soruna şahsen rastlamadım. Çoğu program, isimlerini komut dosyalarını kıran şekillerde değiştirmez. Böylece, basit senaryolar için bir şey gibi pgrepveya pstamamen yeterli bir şeydir ve yaklaşımınız fazlaca görünüyor. Genel dağıtım için bir komut dosyası yazıyorsanız, mümkün olduğu kadar güvenli bir şekilde yazmalısınız.
Scott Severance

2
@ScottSeverance Programları isim değiştirme sorunu değil; Bu ne olursa olsun müdahale gerektirir. Aynı programı çalıştıran diğer kullanıcılar veya aniden komut dosyasının yanlış pozitifler almasına ve dolayısıyla yanlış şeyi yapmasına neden olacak benzer adlara sahip diğer programlar. Ben sadece "çoğunlukla çalışır" yerine "işleri" tercih ederim.
geirha

2
Ben yanlış konuştum. Ancak çoğumuz tek kullanıcılı sistemler kullanıyoruz. Ve çok kullanıcılı bir durumda, kullanıcı adı için grep kolaydır.
Scott Severance

1
Komut dosyanız çalışma sırasında başarısız olursa ve dosyanın kilidini açmadan önce ölürse ne olur?
jp093121

2
@ jp093121 EXIT tuzağı, komut dosyası çıktığında tetiklenir. Komut sonuna, bir çıkış komutuna ulaştığından veya bir komut aldığından veya kullanılabildiği için çıkıp çıkmadığı, rmkomut çalıştırılır. Tuzak kurulduktan sonra sona erdiği sürece kilit gitmiş olmalı.
geirha

18

Kullandığım şey bu:

#!/bin/bash

#check if abc is running
if pgrep abc >/dev/null 2>&1
  then
     # abc is running
  else
     # abc is not running
fi

Basit İngilizce'de: 'pgrep' 0 döndürürse, işlem devam eder, aksi halde olmaz.


İlgili okuma:

Bash Scripting :: String Karşılaştırmaları

Ubuntu El Kitapları pgrep


teşekkürler! Bunu da denedim, mükemmel olarak da çalışıyor :)
Nirmik

pgrepDaha önce bahsedilen aynı 15 karakter limitine "özelliğe" sahip, bu nedenle örneğin pgrep gnome-power-manageraynı zamanda başarısız olur
Thorsen

1
Pgrep'in -xseçeneğini kullandığınızdan emin olun : "Yalnızca adı (veya -f belirtilmişse komut satırı) tam olarak eşleşen işlemlerle eşleşir."
Alastair Irvine,

5

Genelde pidof -x $(basename $0)çalışıp çalışmadığını kontrol etmek için genellikle komut dosyalarımda bulunur.


2

@ Rommel-cid'nin fikrine bağlı olarak, pidof|| (||) işlem yoksa bir komutu çalıştırmak ve & & işlem varsa bir şeyi çalıştırmak, böylece hızlı / / / / koşullu koşulu oluşturmak. Örneğin, burada çalışan bir işlem (işlem adı "chrome" olan krom tarayıcım) ve mevcut olmayan bir işlem için bir test var. Standart çıktıyı 1> / dev / null kullanarak bastırarak bastırmıştım:

$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
 instead"
it's not running? ok i'll run instead
$

1

Kontrol etmem gereken ikili sistem genelinde kurulu olmadığı için "basit" çözümlerin hiçbiri benim için işe yaramadı, bu yüzden sırayla ps -ef | grepyaklaşım kullanmayı gerektiren yolu kontrol etmem gerekiyor :

app="$_sdir/Logic 1.2.18 (64-bit)/Logic"

app_pid=`ps -ef | grep "$app" | awk '{print $2}'`

if `ps -p $app_pid > /dev/null`; then
    echo "An instance of logic analyzer is appear to be running."
    echo "Not starting another instance."
    exit 5
else
    nohup "$app" &> /dev/null &
fi

0

Sorununuz için aklıma gelen ilk şey:
ps aux | grep -i abcÇalışıyorsa sürecin ayrıntılarını gösterecektir. Çalışmakta olduğu satır sayısını veya süreyi eşleştirebilir ve sıfır veya başka bir manipülasyonla karşılaştırabilirsiniz. Yukarıdaki komutu çalıştırdığınızda, size en az bir satır çıktı gösterecektir, yani bu grep komutunun yarattığı işlem hakkında detay.
Bu basit bir hack olarak yapmalı. Bash betiğine koyun ve yardımcı olup olmadığına bakın.


0

Kullanarak start-stop-daemon:

/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2

Normal kullanıcı olarak çalışır.


0

@John Vrbanac tarafından gönderilen kabul edilen cevabın benim için işe yaramadığını ve @geirha tarafından verilen cevabın orijinal soruyu cevaplamadığını öğrendim.

John Vrbanac'ın çözümü benim için bir PHP işleminin çalışıp çalışmadığını kontrol etmedi, CentOS 7 kullanıyorum.

@ geirha'nın cevabı yalnızca başka bir örneğe başlamadan önce bir örneğin zaten çalışmamasını sağlar. Bu asıl soru değildi, asıl soru bir sürecin çalışıp çalışmadığını kontrol etmekti.

İşte benim için çalıştı ne:

Diyelim ki sürecim, işlem adında "Jane" dizgesine sahipti. Bu çalışıp çalışmadığını bulur. Bu BASH ve PHP betikleri için çalışıyor.

ps -aux | grep "[J]ane" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
    echo "It's running"
else
    echo "It's not running"
fi

1
Ah, bu bir Ubuntu soru-cevap sitesi olduğu için, buradaki bazı cevapların, Linux'un konu dışı kalması nedeniyle CentOS 7'de çalışmadığı şaşırtıcı değil. Linux'un diğer sürümleri unix.stackexchange.com
Elder Geek

Cevabın yazarı CentOS kullanmasına rağmen, bu cevap ubuntu için hala geçerlidir.
Phillip -Zyan K Lee- Stockmann, 11:16

0
## bash

## function to check if a process is alive and running:

_isRunning() {
    ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}

## example 1: checking if "gedit" is running

if _isRunning gedit; then
    echo "gedit is running"
else
    echo "gedit is not running"
fi

## example 2: start lxpanel if it is not there

if ! _isRunning lxpanel; then
    lxpanel &
fi

## or

_isRunning lxpanel || (lxpanel &)

Not : pgrep -x lxpanelya da iptal edildiğinde bile çalışan pidof lxpanelraporlar lxpanel(zombi); böylece canlı ve çalışan bir süreç elde etmek için kullanmamız psvegrep


-1

23 Eylül 2016'dan itibaren pgrep, muru'nun senaryosunun çalışması için "-x" seçeneğine ihtiyaç duyuyor gibi görünüyor.

#!/bin/bash

if pgrep -x "conky" > /dev/null 2>&1
then
  echo "conky running already"
else
  echo "now starting conky"
  conky
fi
exit 0

Yukarıdaki betiği bir Ubuntu 16.04.1 makinesinde denedim ve test ettim. Keyfini çıkarın!


-1
#!/bin/bash
while [ true ]; do     # Endless loop.
  pid=`pgrep -x ${1}`  # Get a pid.
  if [ -z $pid ]; then # If there is none,
    ${1} &             # Start Param to background.
  else
    sleep 60           # Else wait.
  fi
done

1
Ubuntu'ya Sormaya Hoş Geldiniz! Ne yaptığıyla ilgili ayrıntılı bilgi vermek için bu cevabı düzenlemenizi öneririm . (Ayrıca bkz İyi bir cevap yazmak nasıl? Ask Ubuntu en değerli kabul edilen cevapların ne tür hakkında genel öneri niteliğinde değildir.)
David Foerster

-3

isProcessRunning () {if [$ ($ 1 pidof)> / dev / null]; daha sonra retval = 'true'; başka bir retval = 'false'; fi; echo $ retval; }

isProcessRunning geany

doğru

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.