İşlemin çalışıp çalışmadığını belirlemek için Linux / Unix komutu?


99

Belirli bir işlemin çalışıp çalışmadığını belirleyecek, platformdan bağımsız (Linux / Unix | OSX) bir kabuk / bash komutuna ihtiyacım var. örneğin mysqld, httpd... Bunu yapmanın en kolay yolu / komut nedir?

Yanıtlar:


170

İken pidofve pgrepçalışan ne belirlemek için harika araçlardır, bunlar, ne yazık ki, her ikisi de bazı işletim sistemlerinde kullanılamaz. Kesin bir arıza güvenliği, aşağıdakileri kullanmak olacaktır:ps cax | grep command

Gentoo Linux üzerindeki çıktı:

14484? S 0:00 apache2
14667? S 0:00 apache2
19620? Sl 0:00 apache2
21132? Ss 0:04 apache2

OS X'teki çıktı:

42582 ?? Z 0: 00.00 (smbclient)
46529 ?? Z 0: 00.00 (smbclient)
46539 ?? Z 0: 00.00 (smbclient)
46547 ?? Z 0: 00.00 (smbclient)
46586 ?? Z 0: 00.00 (smbclient)
46594 ?? Z 0: 00.00 (smbclient)

Hem Linux hem de OS X'te grep bir çıkış kodu döndürür, böylece işlemin bulunup bulunmadığını kontrol etmek kolaydır:

#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

Ayrıca, PID'lerin listesini istiyorsanız, bunlar için de kolayca grep yapabilirsiniz:

ps cax | grep httpd | grep -o '^ [] * [0-9] *'

Linux ve OS X'te kimin çıktısı aynıdır:

3519 3521 3523 3524

Aşağıdakinin çıktısı boş bir dizedir ve bu yaklaşımı çalışmayan işlemler için güvenli hale getirir:

Eko ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'

Bu yaklaşım, basit bir boş dizi testi yazmak, ardından keşfedilen PID'ler aracılığıyla yineleme yapmak için uygundur.

#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
  echo "Process not running." 1>&2
  exit 1
else
  for PID in $PIDS; do
    echo $PID
  done
fi

Yürütme izinleriyle (chmod + x çalışıyor) bir dosyaya ("çalışan" adlı) kaydedip bir parametre ile çalıştırarak test edebilirsiniz: ./running "httpd"

#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

UYARI!!!

Lütfen ps ax, Linux çıktısında görüldüğü gibi, bunun sadece süreçlerle değil, aynı zamanda o programa aktarılan argümanlarla da eşleştiği anlamına gelen çıktısını ayrıştırdığınızı unutmayın . Bu yöntemi kullanırken olabildiğince spesifik ./running "mysql"olmanızı şiddetle tavsiye ederim (örneğin , 'mysqld' işlemleriyle de eşleşir). whichMümkünse tam bir yolu kontrol etmek için kullanmanızı şiddetle tavsiye ederim .


Referanslar:

http://linux.about.com/od/commands/l/blcmdl1_ps.htm

http://linux.about.com/od/commands/l/blcmdl1_grep.htm


İşlem çalışıyor olabilir, ancak durdurulabilir. Dolayısıyla, amaç mysqld veya httpd'nin "çalışır durumda" (yanıt veriyor) olup olmadığını test etmekse, durdurulup durdurulmadığını da kontrol etmelisiniz.
oluc

2
Üzgünüm, ama cevap anlamsal bir bakış açısından kesinlikle doğru olsa da, süreç arg vektöründe model eşleştirerek bir süreç bulmaya tamamen karşıyım. Böyle bir yaklaşım er ya da geç başarısız olmaya mahkumdur (aslında daha fazla kontrole ihtiyaç olduğunu söyleyerek bunu kendiniz kabul edersiniz). Ayrı bir cevaba kendi tavsiyemi ekledim.
peterh

6
grepAyrıca kendisi mesela (koşu bulacaksınız ps cax | grep randomnameçünkü her zaman 0 döndürür grepbulur grep randomname) ... (Bu açıktır umut Bir düzeltme örneğin süreç adının ilk harfi, köşeli parantezler içinde eklemektir. ps cax | grep [r]andomname.
Kyle G'ye

ps cax | rev | cut -f1 -d' ' | revdaha kolay ayrıştırmak için yalnızca ad sütununu gösterecektir.
Tyzoid

1
ps caxkomut adını tam olarak vermeyebilir. Örneğin, "chromium-browser" yerine "chromium-browse" yazar.
jarno

25

PID'yi Bilmelisiniz!

Süreç argümanlarında (gibi pgrep "mysqld") bir tür örüntü tanıma yapmaya çalışarak bir süreç bulmak , er ya da geç başarısız olmaya mahkum olan bir stratejidir. Ya çalışan iki mysqld varsa? Bu yaklaşımı unutun. Geçici olarak düzeltebilirsiniz ve bir veya iki yıl işe yarayabilir, ancak daha sonra düşünmediğiniz bir şey olur.

Yalnızca işlem kimliği (pid) gerçekten benzersizdir.

Arka planda bir şey başlattığınızda her zaman pid'i saklayın. Bash'de bu $!Bash değişkeni ile yapılabilir . Bunu yaparak kendinizi ÇOK sıkıntıdan kurtaracaksınız.

İşlemin çalışıp çalışmadığı nasıl belirlenir (pid ile)

Şimdi soru pid'in çalışıp çalışmadığını nasıl anlayacağına dönüşüyor.

Yapmanız gereken sadece:

ps -o pid = -p <pid>

Bu POSIX ve dolayısıyla taşınabilir. İşlem çalışıyorsa pid'in kendisini döndürür veya işlem çalışmıyorsa hiçbir şey döndürmez. Kesin olarak söylemek gerekirse, komut tek bir sütun döndürecektir pid, ancak boş bir başlık başlığı (eşittir işaretinden hemen önce gelen şeyler) verdiğimizden ve bu istenen tek sütun olduğundan, ps komutu üstbilgiyi hiç kullanmayacaktır. İstediğimiz şey bu çünkü ayrıştırmayı kolaylaştırıyor.

Bu, Linux, BSD, Solaris vb. Üzerinde çalışacaktır.

Başka bir strateji, yukarıdaki pskomuttan çıkış değerini test etmektir . İşlem çalışıyorsa sıfır, çalışmıyorsa sıfır olmamalıdır. POSIX belirtimi, psbir hata oluştuğunda> 0'dan çıkılması gerektiğini söylüyor, ancak neyin "bir hata" oluşturduğu bana açık değil. Bu nedenle, tüm Unix / Linux platformlarında da işe yarayacağından oldukça emin olsam da kişisel olarak bu stratejiyi kullanmıyorum.


1
Ancak bu, bir hizmetin çalışıp çalışmadığını belirleyen soruyu yanıtlamaz. PID eğer bu nedenle bu yanıt geçerlidir, bu gibi durumlarda bilinen olmayacak do PID biliyorum.
Highway of Life

2
Yanlış. Yorumun tüm amacı, bir adım geri atmak ve kendinizi ilk önce grep <sometext>belirli bir süreci bulmak için bir şekilde yapmak zorunda olduğunuz durumda bulursanız, süreci başlattığınızda yanlış bir şey yapmışsınızdır, IMHO. OP'nin sorusundan alıyorum ki, sürecin nasıl başlatılacağı üzerinde gerçekten kontrol sahibi.
peterh

2
OP sorusu için daha doğru "terim", "bir hizmetin çalışıp çalışmadığını belirlemek için platformlar arası komut" olmalıydı; bu, kontrolü çalıştıran sistemle aynı değil, bir dış sistemdir, bu nedenle PID, hiç biliniyor.
Highway of Life

2
Bu kusursuz değil. İlgilendiğiniz süreç, sistem PID'lerin toparlanmasına yetecek kadar uzun süre kaldıktan sonra ölmüş olabilir ve daha sonra başka bir işleme, aradığınız aynı PID tahsis edilmiş olabilir. stackoverflow.com/questions/11323410/linux-pid-recycling
claymation

1
@claymation. Doğru tespit. Ancak PID yöntemi, aynı hizmetin yanlışlıkla iki örneğini başlatmaktan çok daha düşük bir olasılık olduğundan, PID yöntemi, işlem değişkenlerinde kalıp eşleştirmesinden daha iyidir. Sadece iki sentim. :-)
peterh

15

Çoğu Linux dağıtımında pidof(8) kullanabilirsiniz .

Belirtilen işlemlerin tüm çalışan örneklerinin işlem kimliklerini yazdırır veya çalışan örnek yoksa hiçbir şey yazdırmaz.

Örneğin, sistemimde (dört örneğim bashve bir remminaçalışma örneğim var):

$ pidof bash remmina
6148 6147 6144 5603 21598

Başkalarının haklı olarak belirttiği gibi , başka Birliklere göre pgrepveya bunların bir kombinasyonu psve grepaynı şeyi başaracaktır.


+1 pidof httpdRed Hat 5'te işe yarıyor. Ama Red Hat pidof
4'ümde

Aslında, bu komut düşündüğümden daha az yaygın, bunu daha net hale getirmek için cevabımı düzenledim.
Frédéric Hamidi

Gerçekten güzel ve temiz cevap. (desteklenen sistemlerde). Teşekkür ederim.
Mtl Dev

7

Bu, Unix, BSD ve Linux'un çoğu çeşidinde çalışmalıdır:

PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep

Test edildi:

  • SunOS 5.10 [Bundan dolayı PATH=...]
  • Linux 2.6.32 (CentOS)
  • Linux 3.0.0 (Ubuntu)
  • Darwin 11.2.0
  • FreeBSD 9.0-KARARLI
  • Red Hat Enterprise Linux ES sürüm 4
  • Red Hat Enterprise Linux Server sürüm 5

2
+1 Evet, basitçe ps. grepps aux | grep [h]ttpd
İkinciden

Burada köşeli parantez hilesini ana değişkene bir değişken eklemeyi kolaylaştırmak için kullanmadım grep.
Johnsyweb

1
Pekala;) Red Hat AS 4 ve Red Hat AP 5'te test ettim. Tabii ki çalışıyorum! Böylece listenize şunları ekleyebilirsiniz: Red Hat Enterprise Linux ES sürüm 4 ve Red Hat Enterprise Linux Server sürüm 5 . Şerefe
olibre

@Downvoter: Neden? Ne kaçırdım? Anladığım kadarıyla, kabul edilen cevap aynı aramayı yapıyor!
Johnsyweb

6

En basit yol, ps ve grep kullanmaktır:

command="httpd"
running=`ps ax | grep -v grep | grep $command | wc -l`
if [ running -gt 0 ]; then
    echo "Command is running"
else
    echo "Command is not running"
fi

Komutunuzda bazı komut argümanları varsa, ilgilenmediğiniz diğer olası işlemleri filtrelemek için 'grep $ command'den sonra daha fazla' grep cmd_arg1 'koyabilirsiniz.

Örnek: sağlanan bağımsız değişkenle herhangi bir java işlemi olup olmadığını bana göster:

-Djava.util.logging.config.file = logging.properties

çalışıyor

ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l

2
Aslında kullanmak, kullanma ps caxihtiyacını ortadan kaldırır grep -v. Örneğin Yani, kullanabilirsiniz: ps cax | grep java > /dev/null || echo "Java not running".
Highway of Life

1
3. satırda hata var. lütfen "çalışıyor" u "$ running" olarak değiştirin.
Programcı

5

Küçük bir ekleme: -cps'ye bayrak eklerseniz , grep sürecini içeren satırı grep -vdaha sonra kaldırmanız gerekmez . Yani

ps acux | grep cron

bir bsd-ish sisteminde ihtiyacınız olan tüm yazı yazmaktır (bu, MacOSX'i içerir) Daha -uaz bilgiye ihtiyacınız olursa , uzak bırakabilirsiniz .

Yerel pskomutun genetiğinin SysV'ye geri döndüğü bir sistemde ,

ps -e |grep cron

veya

ps -el |grep cron 

pid ve işlem adından daha fazlasını içeren bir liste için. Elbette bu -o <field,field,...>seçeneği kullanarak yazdırmak için belirli alanları seçebilirsiniz .


Bu cevap nasıl taşınabilir? (Ps komutunun farklı biçimlerinin farklı platformlarda kullanılması gerektiğini söylüyorsunuz)
peterh

ps maalesef aynı sonuç için atalarına bağlı olarak farklı seçeneklere sahip araçlardan biridir. Dolayısıyla, bunun etrafına kendi (başka hiçbir şeyle uyumsuz) sarıcınızı yazmadığınız sürece, gidilecek yol, mirasın ana hatlarını bilmek ve buna göre uyum sağlamak olacaktır. Komut dosyası oluştururken durum farklıdır - burada hangi dalda olduğunuzu belirlemek ve betiğinizin davranışını uyarlamak için bu farklılıkları kullanırsınız. Alt satır: ikisini de bilmeniz gerekecek. Ünlü örnek: Larry Wall'un "yapılandır" betiği. Ünlü alıntı: Tebrikler, Eunice'i yönetmiyorsun.
Tatjana Heuser

5

Çeşitli önerileri bir araya getirdiğimde, bulabildiğim en temiz sürüm (kelimelerin bazı kısımlarını tetikleyen güvenilmez grep olmadan):

kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

kill -0 işlemi sonlandırmaz ancak var olup olmadığını kontrol eder ve ardından true değerini döndürür, sisteminizde pidof yoksa, işlemi başlattığınızda pid'i saklayın:

$ mysql &
$ echo $! > pid_stored

sonra senaryoda:

kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

3

Kullanıyorum pgrep -l httpdama herhangi bir platformda mevcut olduğundan emin değilim ...
OSX'te kim onaylayabilir?


Teşekkürler @Johnsyweb. Bir de kontrol edebilir misin pidoflütfen? Tamam yaptın. Teşekkür ederim. Öyleyse OSX üzerinde çalışan başka bir şey bulmalıyız ... Temel ps|grepçözümünüz tek çözüm olabilir ;-)
olibre

1

İşleminizin PID'sini bilmelisiniz.

Başlattığınızda, PID'si $!değişkene kaydedilecektir . Bu PID'yi bir dosyaya kaydedin.

Daha sonra bu PID'nin çalışan bir sürece karşılık gelip gelmediğini kontrol etmeniz gerekecektir. İşte tam bir iskelet komut dosyası:

FILE="/tmp/myapp.pid"

if [ -f $FILE ];
then
   PID=$(cat $FILE)
else
   PID=1
fi

ps -o pid= -p $PID
if [ $? -eq 0 ]; then
  echo "Process already running."  
else
  echo "Starting process."
  run_my_app &
  echo $! > $FILE
fi

Dayanarak cevap ait peterh. Belirli bir PID'nin çalışıp çalışmadığını bilmenin püf noktası ps -o pid= -p $PIDtalimattadır.


0

Bu yaklaşım, 'ps', 'pidof' ve rest komutlarının kullanılamadığı durumlarda kullanılabilir. Araçlarımda / betiklerimde / programlarımda kişisel olarak çok sık procfs kullanıyorum.

   egrep -m1  "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3

Neler olduğunu küçük bir açıklama:

  1. -m1 - ilk maçta işlemi durdur
  2. "mysqld $ | httpd $" - grep, mysqld VEYA httpd ile biten satırlarla eşleşir
  3. / proc / [0-9] * - bash, herhangi bir sayıyla başlayan satırla eşleşir
  4. kes - çıktıyı '/' sınırlayıcıyla bölün ve alan 3'ü çıkarın

0

Bu, temel adı "krom tarayıcı" olan işlemlerin sayısını yazdırır:

ps -e -o args= | awk 'BEGIN{c=0}{
 if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets.
 if($1==cmd){c++}
}END{print c}' cmd="chromium-browser"

Bu "0" yazdırırsa, işlem çalışmıyordur. Komut, işlem yolunun kesme boşluğu içermediğini varsayar. Bunu askıya alınmış süreçlerle veya zombi işlemleriyle test etmedim.

Linux'ta alternatif gwakolarak kullanılarak test edilmiştir awk.

İşte bazı örnek kullanımlarla daha çok yönlü bir çözüm:

#!/bin/sh
isProcessRunning() {
if [ "${1-}" = "-q" ]; then
 local quiet=1;
 shift
else
 local quiet=0;
fi
ps -e -o pid,args= | awk 'BEGIN{status=1}{
 name=$2
 if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets.
 if(name==cmd){status=0; if(q){exit}else{print $0}}
}END{exit status}' cmd="$1" q=$quiet
}

process='chromium-browser'

printf "Process \"${process}\" is "
if isProcessRunning -q "$process" 
 then printf "running.\n"
 else printf "not running.\n"; fi

printf "Listing of matching processes (PID and process name with command line arguments):\n"
isProcessRunning "$process"

0

İşte benim versiyonum. Özellikleri:

  • tam program adını kontrol eder (fonksiyonun ilk argümanı). "mysql" araması çalışan "mysqld" ile eşleşmeyecek
  • program argümanlarını arar (fonksiyonun ikinci argümanı)

senaryo:

#!/bin/bash

# $1 - cmd
# $2 - args
# return: 0 - no error, running; 1 - error, not running
function isRunning() {
    for i in $(pidof $1); do
        cat /proc/$i/cmdline | tr '\000' ' ' | grep -F -e "$2" 1>&2> /dev/null
        if [ $? -eq 0 ]; then
            return 0
        fi
    done
    return 1
}

isRunning java "-Djava.util.logging.config.file=logging.properties"
if [ $? -ne 0 ]; then
    echo "not running, starting..."
fi

0

Cevapların hiçbiri benim için işe yaramadı, bu yüzden benimki:

process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
  echo "Process is not running."
else
  echo "Process is running."
fi

Açıklama:

|tr -d '\n'

Bu, terminal tarafından oluşturulan şaryo dönüşünü kaldırır. Gerisi bu yazı ile açıklanabilir .


-1

Aşağıdaki kabuk işlevi, yalnızca POSIX standart komutlarına ve seçeneklerine dayanmaktadır (eğer yoksa) Unix ve linux sistemlerin çoğunda çalışmalıdır. :

isPidRunning() {
  cmd=`
    PATH=\`getconf PATH\` export PATH
    ps -e -o pid= -o comm= |
      awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}'
  `
  [ -n "$cmd" ] &&
    printf "%s is running\n%s\n\n" "$1" "$cmd" ||
    printf "%s is not running\n\n" $1
  [ -n "$cmd" ]
}

$ isPidRunning httpd
httpd is running
586 /usr/apache/bin/httpd
588 /usr/apache/bin/httpd

$ isPidRunning ksh
ksh is running
5230 ksh

$ isPidRunning bash
bash is not running

Şüpheli "0]" komut adı geçildiğinde boğulacağını ve ayrıca adlarında gömülü boşluk bulunan işlemleri tanımlayamayacağını unutmayın.

En çok oy alan ve kabul edilen çözümün taşınabilir olmayan psseçenekler gerektirdiğini ve popülerliğine rağmen her Unix / Linux makinesinde olması garanti edilmeyen bir kabuğu ücretsiz olarak kullandığını da unutmayın ( bash)


$ isPidRunning 0]baskılar örneğin "0] çalışıyor 3 [ksoftirqd / 0] 8 [rcuop / 0] 17 [rcuos / 0] 26 [rcuob / 0] 34 [migration / 0] 35 [watchdog / 0]" burada.
jarno

O PATH şeyine ne için ihtiyacın var?
jarno

Çözümü burada daha da geliştirdim .
jarno

@jarno PATH ayarı, komut dosyasının taşınabilir olması için bir gerekliliktir. Aksi takdirde, en azından Solaris 10 ve daha eski sürümlerde ve muhtemelen diğer Unix uygulamalarında başarısız olur.
jlliagre

1
@jarno Bunu yapabilirim ama bu PATH ayarını awk için de tekrar etmem gerekecek. POSIX öncesi sözdizimi bourne kabuklarla taşınabilir olması için eski arka işaret sözdizimine geri döndüğümü unutmayın.
jlliagre
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.