Bash betiği SIGHUP görmüyor mu?


11

Aşağıdaki senaryo var:

#!/bin/bash
echo "We are $$"
trap "echo HUP" SIGHUP
cat    # wait indefinitely

Gönderirken SIGHUP(kullanarak kill -HUP pid) hiçbir şey olmuyor.

Senaryoyu biraz değiştirirsem:

#!/bin/bash
echo "We are $$"
trap "kill -- -$BASHPID" EXIT    # add this
trap "echo HUP" SIGHUP
cat    # wait indefinitely

... sonra komut dosyası echo HUPçıkar çıkmaz doğru yapar (Ctrl + C tuşlarına bastığımda):

roger@roger-pc:~ $ ./hupper.sh 
We are 6233
^CHUP

Neler oluyor? SIGHUPBu komut dosyasına nasıl bir sinyal göndermeliyim (olması gerekmez )?


4
catİşlem tamamlandığında sinyal iletilir ve sinyal işleyici yürütülür . Orijinal komut dosyanızı deneyin Ctrl+Dve catişlemden çıkmak için tuşuna basın . İken catsüreç ön planda olduğunu HUPsinyali üzerinde bir etki değildir. İle catdeğiştirmeyi tekrar deneyin read(yerleşik bir kabuk).
Kusalananda

Mükemmel. Birisi bunu bir cevaba dönüştürmeyi seviyor mu?
Roger Lipscombe

Bunun bu şekilde çalıştığını biliyorum, ama benden daha fazla içgörüye sahip olan birinin neden cevabı ve nerede olduğunu cevaplamasına izin vereceğim.
Kusalananda

while true; do read; doneSonunda kullandım , aksi takdirde metin girmek de çıkmasına neden olur ve Ctrl + C'de çıkmasını istiyorum.
Roger Lipscombe

Yanıtlar:


21

Bash el kitabı şunları belirtir:

Bash bir komutun tamamlanmasını bekliyor ve tuzağı ayarlanmış bir sinyal alıyorsa, komut tamamlanıncaya kadar tuzak yürütülmez.

Bu, sinyali bashgönderdiğinizde sinyal alınmasına rağmen, SIGHUP üzerindeki tuzağınızın yalnızca catsona erdiğinde çağrılacağı anlamına gelir .

Bu davranış istenmeyen bir durumsa, ya bashyerleşikleri kullanın (örneğin , bunun yerine döngü içinde read+ ) ya da arka plan işlerini kullanın ( Stéphane'nin cevabına bakın ).printfcat


9

@xhienne zaten nedenini açıkladı , ancak sinyalin hemen harekete geçmesini (ve komut dosyasından çıkmamayı ) istiyorsanız, kodunuzu şu şekilde değiştirebilirsiniz:

#! /bin/bash -
interrupted=true
trap 'interrupted=true; echo HUP' HUP

{ cat <&3 3<&- & pid=$!; } 3<&0

while
  wait "$pid"
  ret=$?
  "$interrupted"
do
  interrupted=false
done
exit "$ret"

Dosya tanımlayıcılarıyla yapılan küçük dans, bashstdin'i /dev/nullarka planda başlatılan komutlar için yönlendirdiği gerçeği üzerinde çalışmaktır .


Kod bloğu bir alt kabukta çalıştığı için bu çalışır mı?
Pysis
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.