Bash neden SIGTERM'i görmezden geliyor?


10

Bazen çabucak çıkış yapmak istediğimde yapıyorum kill -15 -1. Bash'in SIGTERM'i görmezden geldiğini fark ettim.

Acaba böyle bash davranışlarının mantığı nedir?

SIGTERM'i iyi bir sebep olmadan görmezden gelmek çok UNIX' değildir, değil mi?

GÜNCELLEME:

herkes için aynı (hayır) etki:

$ kill -TERM $$
$ type kill
kill is a shell builtin
$ command kill -TERM $$
$ /bin/kill -TERM $$

Update2:

Gönderen adam bash :

Bash etkileşimli olduğunda, herhangi bir tuzak olmadığında, SIGTERM'i yok sayar

Yani bilerek yapıldı. Ama neden?


Hangi öldürmeyi kullanıyorsun? /bin/killya da kabuk yerleşimi? İkincisi, kabuğun kendi yerleşimi ile kendini öldürmeyeceğini tahmin ediyorum.
terdon

@terdon: Yerleşik kullandım, ama kendimi öldürmemenin sebebi olduğunu sanmıyorum.
Michał Šrajer

1
Hızlı bir şekilde çıkış yapmak istiyorsanız, Ctrl + d
YoMismo

1
@YoMismo: "X oturumundan çıkış"
Michał Šrajer

2
@ MichałŠrajer: Ctrl-Alt-Backspace bunu benim için Xorg'da yapıyor ... xorg.conf'da etkinleştirmeniz gerekebilir.
Laszlo Valko

Yanıtlar:


10

Birincisi, bu bash'a özgü değil. ATT ksh, tire ve zsh aynı şekilde davranırlar: komut satırı sürümü sırasında SIGTERM ve SIGQUIT'i yok sayarlar; mksh gelince, aynı zamanda bırakmaz ama onlara SIGINT gibi davranır.

Hem ksh kılavuzu hem de bash kılavuzu, SIGTERM'i görmezden gelmeyi şu koşullarda haklı çıkarır:

böylece kill 0interaktif bir kabuğu öldürmez

kill 0işlem grubundaki kabuğun bulunduğu tüm işlemleri öldürür . Özetle, süreç grubu bir terminalde ön planda çalışan tüm süreçlerden veya bir arka plandaki veya askıya alınmış bir işteki tüm süreçlerden oluşur.

Daha doğrusu, iş kontrolü ile modern kabuklarda olan budur . Bu tür kabuklarda, kill 0kabuk kendi başına bir süreç grubunda olacağı için yararlı olmaz. Eski kabuklar (ya da sonrasındaki modern kabuklar set +m) arka plan komutları için işlem grupları oluşturmadı. Bu yüzden, kill 0oturumu kapatmadan tüm arka plan komutlarını öldürmek için komutu kullanabilirsiniz kill 0.

Bununla birlikte, kabuğun bağışıklığının faydalı olduğu başka benzer durumlar da vardır. Bir terminali gezdiren işlemlerinizin olduğu ve oturumu kapatmadan öldürmek istediğiniz durumu düşünün. Birçok sistem pkill, bir terminalde çalışan işlemleri öldürmenize izin veren bir araca sahiptir. Sinyali yoksayan kabuk hariç, geçerli terminalde çalışan tüm işlemleri çalıştırabilir pkill -t $TTYveya pkill -QUIT -t $TTYöldürebilirsiniz.

Bir kabuk normalde kullanıcı onu terk ettiğinde ( exitya da gibi bir komutla logout) ya da terminali girişin sonunu gösterdiğinde (kullanıcı Ctrl+ tuşuna basarak buna neden olabilir D) ya da tamamen ortadan kalkar. Bu son durumda, kabuk SIGHUP sinyalini alır ve bunu görmezden gelmez.

Bir X oturumundan çıkış kill -15 -1yapma durumunuz için bunu yapar, çünkü kabuğun SIGHUP almasına neden olan terminal öykünücüsünü öldürür. Aslında X sunucusunu öldürmek yeterlidir, ancak bu işlem işlem kimliğini bulmayı gerektirir. Aynı komutun bir metin oturumunda çalışmasını istiyorsanız, kullanabilirsiniz kill -15 -1; exit. Zaten parmaklarınızın ucunda olması oldukça tehlikeli bir komut.

¹ Bu kural olarak kabuk kılavuzları belirtilmelidir görünmüyor; temel sistem çağrısının bir özelliğidir. POSIX spesifikasyonunda açıkça belirtilmiştir .
² Günümüzde bunu yapmak için, jobs -lsüreç grubu kimliğine sahip işlerin listesini görmek, ardından kill -123 -456 …işlem gruplarını öldürmek için çalıştırın.


5

Bu, sorunuza cevap verebilir:

Bash etkileşimli olduğunda, herhangi bir tuzak olmadığında, SIGTERM'i yok sayar (böylece '0 öldür' etkileşimli bir kabuğu öldürmez) ve SIGINT yakalanır ve işlenir (böylece bekleme yerleşimi kesilebilir). Bash bir SIGINT aldığında, yürütme döngülerinden çıkar. Her durumda, Bash SIGQUIT'i yok sayar. İş kontrolü etkinse (bkz. İş Kontrolü), Bash SIGTTIN, SIGTTOU ve SIGTSTP'yi yok sayar.

Bash tarafından başlatılan yerleşik olmayan komutlar, sinyal işleyicilerinin kabuk tarafından üst öğesinden devralınan değerlere ayarlandığını gösterir. İş kontrolü etkin olmadığında, eşzamansız komutlar, bu devralınan işleyicilere ek olarak SIGINT ve SIGQUIT'i yok sayar. Komutların değiştirilmesi sonucunda çalışan komutlar, klavye tarafından oluşturulan SIGTTIN, SIGTTOU ve SIGTSTP iş kontrol sinyallerini yoksayar.

Bir SIGHUP alındıktan sonra kabuk varsayılan olarak çıkar. Çıkmadan önce, etkileşimli bir kabuk SIGHUP'u çalışan veya durdurulmuş tüm işlere yeniden gönderir. Durdurulmuş işler SIGHUP aldıklarından emin olmak için SIGCONT'a gönderilir. Kabuğun SIGHUP sinyalini belirli bir işe göndermesini önlemek için, reddedilen yerleşik (bkz. Job Control Builtins) olan işler tablosundan kaldırılmalı veya -h disown kullanılarak SIGHUP alınmayacak şekilde işaretlenmelidir.

Huponexit kabuk seçeneği shopt ile ayarlanmışsa (bkz. Shopt Builtin), Bash etkileşimli bir giriş kabuğu çıktığında tüm işlere bir SIGHUP gönderir.

Bash bir komutun tamamlanmasını bekliyor ve tuzağı ayarlanmış bir sinyal alıyorsa, komut tamamlanıncaya kadar tuzak yürütülmez. Bash, wait yerleşimi üzerinden eşzamansız bir komut beklerken, bir tuzağın ayarlandığı bir sinyalin alınması, bekleme yerleşiminin derhal 128'den daha büyük bir çıkış durumu ile geri dönmesine neden olur, hemen sonra tuzak yürütülür.

KAYNAK : GNU Bash kılavuzu


Bunu güncellememde alıntıladım2. İnsan bash'ın bunu yaptığını söyler, ancak böyle bir kararın nedenini açıklamaz. Soru hala devam ediyor - neden?
Michał Šrajer
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.