Bir işlemin arka planda zaten çalışıp çalışmadığını kontrol etmenin yolu (ve buna göre yeniden yürütmeyi atla).


11

İşlem zaten çalışmıyorsa (arka planda) yalnızca belirli bir komutu çalıştıran bir bash komut satırı yapabilir miyim?

Bir komutun çalışıp çalışmadığını * nasıl kontrol edebilirim?

(böylece aralarında bir sonraki komutu ekleyebilirim, &&böylece bir sonraki sadece birincisi doğruysa yürütür).

*: test et, belirle, keşfet, öğren


3
ps -ef | grep -v grep | grep "process_name" || run_command_here
Rahul Patil

1
@RahulPatil sadece pgrep "process_name"yerine kullanabilirsinizps | grep | grep
acele

hmm, şunu unutuyorum ..: D
Rahul Patil

1
Neden bir "kilit" dosyası kullanmıyorsunuz ve ikinci kez başlattığınızda, yalnızca kilit dosyası kaybolduğunda başlatılır.
BitsOfNix

bir sürecin olup olmadığını kontrol etmenin en iyi yolu: stackoverflow.com/questions/3043978/…
Trevor Boyd Smith

Yanıtlar:



3

Bu tekniği zaman zaman kullandım:

$ pgrep <process name> || <process name>

Önce pgrepbunun bu şekilde yapılması kullandı:

$ ps -eaf | grep -q <[p]rocess name> || <process name>

misal

Biraz [p]bunu yapar, böylece grepsonuç olarak kendini bulamazsınız.

$ ps -eaf | grep -q [s]leep || sleep 10

2

Bu zor olabilir, çünkü aynı sürecin bağımsız olarak yaşayan ayrı örneklerine sahip olabilirsiniz. Örneğin, farklı bağlantı noktalarını dinleyen sunucular veya farklı kullanıcılar olarak çalışan hizmetler. Bu örnekleri ayırt etmek için, her birine benzersiz bir etiket atamanız gerekir. Etiket genellikle bir dosyadır, ancak soyut ad alanında yerel bir soket, bir TCP bağlantı noktası vb. Olabilir - herhangi bir benzersiz tanımlayıcı bunu yapar. Etiket bir dosya olduğunda, işlem kimliği (pidfile) veya dosyanın dinlediği adlandırılmış bir boru veya soket vb. İçeren normal bir dosya olabilir. İdeal olarak, etiket istemcilerin bağlanmasına izin veren bir iletişim bitiş noktasıdır bu sürece.

Bu farklı etiket türlerinin her biri, aradığınız örneğin çalışıp çalışmadığını farklı bir şekilde kontrol etmenizi sağlar. Örneğin, yerel bir dosya soketiyle, ona bağlanmayı deneyin ve bu sokette dinleme işlemi yoksa işlemi başlatın. Etiket bir pidfile ise, bu işlem kimliğine sahip bir işlem olup olmadığını kontrol edin, ancak bunun kırılgan olduğuna dikkat edin, çünkü işlem ölmüşse kimliğini yeniden kullanan ilişkisiz bir işlem olabilir. İki istemci sürece kısa bir süre içinde ulaşmaya çalışırsa, her ikisinin de sürecin var olmadığını ve her ikisinin de başlatmayı denediğini unutmayın; Bu yarış koşulundan düzgün şekilde korunmak zor olabilir.

Örneklerin tümü aynı denetim süreci tarafından başlatıldığında yönetilmesi daha kolaydır ve denetim süreci, örneklerin ne zaman öldüğünü algılar ve buna göre tepki verir. Bunu yapabilen birçok servis izleme programı .

Program bilinen bir iletişim uç noktasında yanıt vermezse ve bir denetim programı tarafından yönetilmezse, yoksul adamın etiketi bir pidfile olur: işlem kimliğini içeren bir dosya. İşlemi başlattığınızda, pid'i önceden ayarlanmış bir ada sahip bir dosyaya yazın. Sürecin var olması gerektiğinde, pid dosyasını okuyun ve bu pid ile bir işlem olup olmadığını görün. İşlemi öldürdüğünüzde pidfile dosyasını silin. Denetimsiz bir pidfile ile en belirgin sorun, işlemin ölmesi durumunda, pid'in ilişkisiz bir işlemle tekrar kullanılabilmesidir. Doğru işlemle konuştuğunuzdan emin olmak için en azından işlem adını veya yürütülebilir dosyayı kontrol etmelisiniz. Birçok unix varyantının pgrep komutu vardır:pgrep SOMENAME adı, alt kullanıcı olarak SOMENAME içeren işlemleri listeler, belirli bir kullanıcıyı sınırlamak, tam bir eşleşme istemek, “işlem adı” gibi olası birkaç kavramdan hangisinin kullanıldığını değiştirmek için ek seçeneklerle listeler.


1

Bu yaklaşımı kullanabilirsiniz:

if [[ -z $(ps -C appname -opid=) ]]; then
    appname && secondapp
fi

1

Diğer seçenekler:

  • pgrep -xq processname
    • GNU / Linux'ta sadece ilk 15 karakterle eşleşir
    • OS X'te ata içermez
  • ps -eo comm= | sed 's|.*/||' | grep -xq processname
    • GNU / Linux'ta sadece ilk 15 karakterle eşleşir
    • sed 's|.*/||' OS X'teki dirname parçalarını kaldırır

GNU / Linux'ta ps -o commkomut adlarını 15 karaktere böler pgrepve ps -Cyalnızca ilk 15 karakterle eşleşir.

ps -C (eşleşme komut adları) OS X'te desteklenmez.

OS X'te ps -o commkomutların mutlak yollarını ps -co commyazdırır ve yalnızca komut adlarını yazdırır. GNU'da ps -o commyalnızca komut adlarını yazdırır ve -cfarklı bir anlamı vardır.

OS X'in eklentisi, olmadan ata işlemleri (bash, Terminal veya launchd gibi) içermez -a. GNU'nun önceliği varsayılan olarak bunları içerir ve desteklemez -a.

grep -xve pgrep -xima etmeyin -F, bu nedenle -Fxişlem adı normal ifade karakterleri içeriyorsa kullanın .


-C benim
cygwin'de

1

Üzgünüm ama aynı komut satırı 'ps' sonucunda iki kez görüneceğinden tüm bu çözümler contab'ı desteklemiyor.

İşte benim:

## Test pour voir si le même script tourne déjà
## Un fichier .pid est utilisé pour stocké le numéro de process
## Si le pid est en train de tourner alors on sort.
lock_file=$0".pid"
[ -r $lock_file ] && read pid <$lock_file
if [ "$pid" -gt 1 ] && [ `ps --no-headers -p "$pid" | wc -l` -gt 0 ] ; then
    echo "WARNING : le process $pid tourne deja : $0"
    ps -edf | grep `basename $0` | grep -v grep
    echo "WARNING : Arrêt de cette instance ($$)."
    exit 7
fi
echo $$ >$lock_file

Ne için özür dilerim? Contab nedir? Bir cronişin içinden kontrol etmek mi demek istiyorsun ?
Anthon

0

Bash ile

#!/usr/bin/env bash

[[ $# -eq 0 ]] && { echo -e "Usage:\t\t $0 <Process_name>  <Command here>"; exit 1;  }

ifnotrun(){
        local p=$1
        if ! ps -C "$1" -opid=
        then
                cmd=($@)
                echo ${cmd[@]:1}
        else
                echo "Process \"$p\" Already Running.."
                exit 1
        fi

}

ifnotrun $*

Not: - echoÇıktı Tamam görünüyorsa çıkarın .


0

Komutu beckgreoud'da çalıştırdığınız durumu açıklayacağım. "$!" son arka plan işleminin PID'sini kaydedin. Yani, yukarıdaki yanıtları izleyerek işlem tablolarında bulmak için kullanabilirsiniz:

sleep 4 &
ps -ef | grep -w  $!  ...

Yerleşik komut "jobs" - şunu deneyin:

sleep 4&
J=`jobs`
while [ "$J" ]; do
        sleep 1
        jobs # This line flush the jobs' bufer.
        J=`jobs`
done

"&&" seçeneği ile ilgili olarak

&& yerine wait komutunu kullanın. Aşağıdaki örnekte myproc2, myproc1 bitinceye kadar çalışmaz:

myproc1 &
wait
myproc2

0

İşleminizin durumunu öğrenin:

ps -lp $(pgrep <YOUR_PROCESS_NAME>) | tail -1 | awk '{print $11}'

Referans:

D    uninterruptible sleep (usually IO)
R    running or runnable (on run queue)
S    interruptible sleep (waiting for an event to complete)
T    stopped, either by a job control signal or because it is being traced
W    paging (not valid since the 2.6.xx kernel)
X    dead (should never be seen)
Z    defunct ("zombie") process, terminated but not reaped by its parent

Örneğin, bir tmux oturumunda sox sürecimi koşullu olarak oynatmak veya duraklatmak için kullandım:

/usr/local/bin/tmux if-shell -t sox "[ $(ps -lp $(pgrep sox) | tail -1 | awk '{print $11}') == 'T' ]" \
  'send -t sox "fg" Enter' \
  'send -t sox C-z'

-1

Bir komut dosyasında kullanabilirsiniz:

if [ `ps -ef | grep "script.sh" | grep -v grep | wc -l` -gt 1 ] ; then
echo "RUNNING...."
else
echo "NOT RUNNING..."
fi
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.