Belirli bir PID'nin çalışıp çalışmadığını nasıl kontrol etmeliyim?


16

PID toplamak için günlük dosyalarını ayrıştıran ve daha sonra bu PID çalışıp çalışmadığını denetler Perl komut dosyası yazıyorum. Bu kontrolü yapmanın en iyi yolunu düşünmeye çalışıyorum. Açıkçası, şöyle bir şey yapabilirim:

system("ps $pid > /dev/null") && print "Not running\n";

Ancak, mümkünse sistem çağrısından kaçınmayı tercih ederim. Bu nedenle /procdosya sistemini kullanabileceğimi düşündüm (taşınabilirlik bir endişe değildir, bu her zaman bir Linux sisteminde çalışacaktır). Örneğin:

if(! -d "/proc/$pid"){
    print "Not running\n";
}

Bu güvenli mi? Herhangi bir /proc/$pid/dizin yoksa ilişkili PID'nin çalışmadığını her zaman kabul edebilir miyim ? AFAIK'in pskendisini /proczaten bilgilerini aldığı için bekliyorum ama bu üretim kodu için olduğundan emin olmak istiyorum.

Peki, çalışan bir işlemin dizini olmadığı /proc/PIDveya bir /proc/PIDdizinin bulunduğu ve işlemin çalışmadığı durumlar olabilir mi? psDizinin varlığını denetlemeyi tercih etmenin herhangi bir nedeni var mı ?


2
ayrıca kill0 sinyali kullanan perl işlevi vardır, bu da öldürme yapmaz, ancak bunu yapıp yapamayacağınızı söyler (yani bu işlemi sinyal almak için izne ihtiyacınız vardır).
meuh

1
'/ proc / $ PID' bunu Linux'ta yapıyorsanız iyi olur.
likewhoa

7
@terdon Hangi yöntemi kullanırsanız kullanın (ve kill -0en iyisi), bunun yalnızca belirtilen PID'de çalışan bir işlem olup olmadığını gösterir . Sürecin hala bir milisaniye sonra çalışıp çalışmayacağını söylemez ve işlemin ilgilendiğiniz işlem olup olmadığını veya ilginç işlem öldükten sonra aynı PID'yi atanmış ilişkisiz bir işlem olup olmadığını söylemez. . Belirli bir PID'nin çalışıp çalışmadığını test etmek neredeyse her zaman bir hatadır : bunun yarış koşullarına eğilimli olmadığı çok az koşul vardır.
Gilles 'SO- kötü olmayı bırak'

1
@Gilles gerçekten de süreç adını kontrol etmeliyim. Ancak, bu durumda, milisaniye sonra bir durum değişikliği olup olmadığı umurumda değil. Ben bir dB ve pids ile ilgili bir dosya etkin olarak listelenen işlemleri var. Ben sadece DB çalıştığını düşünüyor bir şey aslında çalışmıyor olup olmadığını kontrol etmek gerekir ve tekrar rastgele başlayamaz bilmek kurulum üzerinde yeterli kontrole sahip.
terdon

3
@ MickeyL vay be, bana söylendi. Aslında bu kadar kötü ve tehlikeli olanı açıklama zahmetine girmiş olsaydınız, kendi parlaklığınızı kutlamak yerine faydalı bir yorum olurdu. Haklı olduğundan şüphe duymuyorum, asla programcı olduğunu iddia etmedim, bu yüzden soruyu sordum, ama hem hakaret hem de yararsız olmayı başardın.
terdon

Yanıtlar:


20

Perl işlevi kill(0,$pid)kullanılabilir.

Dönüş kodu 1 ise, PID vardır ve ona bir sinyal göndermenize izin verilir.

Dönüş kodu 0 ise $! 'I kontrol etmeniz gerekir. Bu, işlemin var olduğu anlamına gelen EPERM (izin reddedildi) veya bu durumda işlemin olmadığı ESRCH olabilir.

Kontrol kodunuz şu şekilde çalışıyorsa root sadece öldürmenin dönüş kodunu kontrol etmek için bunu basitleştirebilirsiniz; 0 => hata, 1 => tamam

Örneğin:

% perl -d -e 0

Loading DB routines from perl5db.pl version 1.37
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(-e:1):   0
  DB<1> print kill(0,500)
0
  DB<2> print $!
No such process
  DB<3> print kill(0,1)
0
  DB<4> print $!
Operation not permitted
  DB<5> print kill(0,$$)
1

Bu basit bir fonksiyona dönüştürülebilir

use Errno;

sub test_pid($)
{
  my ($pid)=@_;

  my $not_present=(!kill(0,$pid) && $! == Errno::ESRCH);

  return($not_present);
}

print "PID 500 not present\n" if test_pid(500);
print "PID 1 not present\n" if test_pid(1);
print "PID $$ not present\n" if test_pid($$);

FWIW, bunu nasıl yapabileceğinizi gösteren basit bir fonksiyon ekledim.
Stephen Harris

Evet, sanırım bununla gideceğim. İhtiyacım olan her şeyin if (!kill(0,$pid) && $! =~ /No such process/){ exit; }benzer olduğunu fark ettiğim için yorumumu sildim . ErrnoYine de çözümünüzü seviyorum , teşekkürler. Muhtemelen bununla devam ederken, herhangi birinin temel Linux sorusunu cevaplayabilmesi için bir süre bekleyeceğim.
terdon

2
Eğer /procis monte ardından böylece ad alanında görünür her PID, mevcut olacak -d /proc/$pidtesti olacağını çalışmak ... ama oldukça doğal sistem çağrıları kullanmaktan daha dosya sistemine çıkıyor içerir.
Stephen Harris

Bu kaçınmak istediğim şey, evet.
terdon

2
@terdon: Sadece benim karışıklık olduğunu "Sistem çağrısı" aslında demek "tarafından gerçeğinden geldi fark system- yani bir çağrı çağrı" systemfonksiyonu kendisi değil, bir "sistem çağrısı" . İkincisinden kaçınamazsınız, ama eskisini kesinlikle yapabilirsiniz. Şimdi mantıklı!
user541686

6
  • % 99.9 eminim var olan (ve bir dizin) olup olmadığını kontrol % 98 tekniği kadar güvenilir . % 98'in% 100 olmamasının nedeni, Stephen Harris'in bir yorumda dokunduğu (ve geri döndüğü) bir noktadır - yani dosya sistemi monte edilmemiş olabilir. Bu iddiaya geçerli olabileceğini bir Linux sistemi olmadan hasarlı, bozulmuş bir sistemdir - sonuçta, işler gibi , ve muhtemelen çalışma olmayacak - ve bu kudreti bir üretim sistemi için bir sorun değil yani. Ancak (teorik olarak) asla monte edilmemesi mümkündür (bu, sistemin normal bir duruma gelmesini engelleyebilse de), sökülmemesi kesinlikle mümkündür (test ettim 1/proc/PIDkill 0/proc/procpstoplsof). Ve sistem tamamen hortumlanmadıkça killçalışacaktır.
  • Stephen'ın yorumu “dosya sistemine gitme” ve “yerel sistem çağrılarını kullanma” hakkında konuşuyor. Bunun büyük ölçüde kırmızı bir ringa balığı olduğuna inanıyorum.
    • Evet, herhangi bir erişim denemesi , dosya sistemini bulmak için /proc kök dizinin okunmasını gerektirir . Bu, herhangi bir girişim erişmek için de geçerlidir herhangi şeyler de dahil olmak üzere, mutlak yol adı dosyayı , ve . Bu, kök dizinin sistemin tüm ömrü boyunca (çalışma süresi) kesinlikle bellekte önbelleğe alınacağı kadar sık ​​olur, bu nedenle bu adım herhangi bir disk G / Ç olmadan yapılabilir. Ve bir kez inode'unuz olduğunda , gerçekleşen her şey hafızada./proc/bin/etc/dev/proc
    • Nasıl erişirsiniz /proc? İle stat, open, readdirvb yerli sistem olduğu kadar her bit çağrıları hangi kill.
  • Soru, çalışan bir süreçten bahsediyor. Bu kaygan bir ifade. İşlemin gerçekten çalışıp çalışmadığını test etmek istiyorsanız (yani, çalışma kuyruğunda; belki bazı işlemcilerde geçerli işlem; uyku, bekleme veya durdurulmamışsa), bir yapmanız ve çıktıyı okumanız veya . Ancak sorunuzda veya yorumlarınızda bununla ilgili olduğunuzu gösteren bir ipucu görmüyorum.ps PID /proc/PID/stat

    Ancak odadaki fil, bir zombi 2 sürecinin canlı ve iyi bir süreçten ayırt edilmesinin zor olabileceğidir.  kill 0bir zombi üzerinde çalışır ve var. Zombileri önceki paragrafta listelenen tekniklerle tanımlayabilirsiniz ( çıktıyı yaparak ve okuyarak veya bakarak ). Benim çok hızlı ve rahat (yani çok kapsamlı değil) test ayrıca bir yaparak bunu yapabilirsiniz önerir veya üzerinde , veya - bu zombiler üzerinde başarısız olur. (Ancak, sahip olmadığınız işlemlerde de başarısız olurlar.)/proc/PIDps PID/proc/PID/statreadlinklstat/proc/PID/cwd/proc/PID/root/proc/PID/exe

____________
1  eğer -f( f orce) seçeneği yok iş, deneyin -l( l Azy).
2  yani, çıkmış / ölmüş / feshedilmiş, ancak ebeveyni henüz tamamlanmamış bir süreç wait.


Yanlış yaptığım için sildiğim cevabım hakkındaki yorumunuz için teşekkürler. kill(2)Manpage'in doğrudan işaret ettiğiniz davranışı gösterdiğine inanmıyorum , ancak perlfuncmanpage de gösteriyor. Michael Kerrisk'e sistem kılavuzuyla ilgili ne söyleyeceğini görmek için mail atacağım.
jrw32982

kill(2)0 sinyalini "gönderme" izinleri ile ilgili açıklamak için bir hata raporu hazırladım.
jrw32982 Monica

@ jrw32982: Man sayfasında “ sig argümanı… 0 olabilir, bu durumda hata kontrolü yapılır…” ve “ HATALAR - kill () sistem çağrısı başarısız olur ve şu durumlarda sinyal gönderilmez: … Gönderme işlemi süper kullanıcı değildir ve etkin kullanıcı kimliği, alma işleminin etkin kullanıcı kimliğiyle eşleşmez. … ”Şimdi bundan bahsettiğinize göre, bunun birden fazla şekilde yorumlanabileceğini düşünüyorum, ancak, maalesef, birçok Unix man sayfası bu tarzda yazılmıştır ve satırlar arasında okumanızı gerektirir. Michael, olduğu gibi yeterince açık olduğuna inanabilir.
G-Man, 'Monica'yı Yeniden Başlat' diyor

Michael kill(2)manpage üzerinde bir değişiklik yaptı (henüz çevrimiçi görmüyorum): "sig 0 ise, o zaman sinyal gönderilmez, ancak varlık ve izin kontrolleri yapılır; bu, bir varlığın varlığını kontrol etmek için kullanılabilir işlem kimliği veya arayanın sinyal göndermesine izin verilen işlem grubu kimliği. "
jrw32982 Monica
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.