Ne olur hem olmasıdır bashve pingSIGINT almak ( bashvarlık değil interaktif, hem pingve bashbunu kimden senaryoyu ran interaktif kabuk tarafından terminalin ön plan süreci grubu olarak oluşturulan ve set edilmiş aynı işlem grubunda çalıştırın).
Ancak, bashSIGINT'in eşzamansız olarak, yalnızca o anda çalışan komuttan çıktıktan sonra ilgilenir. bashsadece o anda çalışan komut bir SIGINT’ten ölürse, yani çıkış durumu SIGINT tarafından öldürüldüğünü gösterirse, bu SIGINT’i aldıktan sonra çıkar.
$ bash -c 'sh -c "trap exit\ 0 INT; sleep 10; :"; echo here'
^Chere
Yukarıda, ve bash, Ctrl-C tuşlarına bastığımda SIGINT alıyorum, ancak normalde 0 çıkış koduyla çıkıyor, bu nedenle SIGINT'i yok sayıyor, bu yüzden "burada" görüyoruz.shsleepshbash
pingEn azından iputillerden biri böyle davranır. Kesildiğinde, istatistikleri yazdırır ve ping'lerinin cevaplanıp cevaplanmamasına bağlı olarak 0 veya 1 çıkış durumundan çıkar. Sırasında Ctrl-C tuşlarına basın Yani, ping, çalıştığı bashbastığınız ettik notlar Ctrl-Cama onun SIGINT işleyicilerindeki beri pingnormalde çıkışlar, bashçıkış vermez.
Eğer sleep 1bu döngüye bir giriş ekler ve Ctrl-Cçalışırken basın sleep, çünkü sleepSIGINT üzerinde özel bir işleyicisi yoktur, ölecek ve bashSIGINT'ten öldüğünü bashbildirecek ve bu durumda çıkacak (aslında SIGINT ile kendini öldürecek. kesintiyi ebeveyne bildirmek için).
Neden bashböyle davrandığına gelince , emin değilim ve davranışların her zaman belirleyici olmadığını not ediyorum. Ben sadece sordunuz üzerinde soru bashgeliştirme posta listesine ( Güncelleme : @Jilles şimdi nedenle aşağı çivilenmiş olan onun cevabını ).
Benzer davrandığını bulduğum diğer tek kabuk ksh93'tür (@Jilles tarafından belirtildiği gibish güncelleme, FreeBSD de öyle ). Orada, SIGINT açıkça göz ardı ediliyor gibi görünüyor. Ve ksh93çıkışlar bir komut SIGINT tarafından öldürülür zaman.
bashYukarıdaki gibi aynı davranışı elde edersiniz, aynı zamanda:
ksh -c 'sh -c "kill -INT \$\$"; echo test'
"Test" yazmıyor. Başka bir deyişle, SIGINT ile bekleyen komut, SIGINT'in ölümünü beklemişse, kendisi de o SIGINT'i almadıysa, çıkar.
Etrafta bir çalışma, şunu eklemek olacaktır:
trap 'exit 130' INT
bashBir SIGINT aldıktan sonra çıkmaya zorlamak için komut dosyasının en üstünde ( her durumda, SIGINT'in yalnızca şu anda çalışan komuttan çıktıktan sonra, eşzamanlı olarak işlenmeyeceğini unutmayın).
İdeal olarak, ebeveynimize bir SIGINT'ten öldüğümüzü bildirmek isteriz ( bashörneğin, başka bir komut dosyası varsa , o bashkomut dosyası da kesilir). Bir exit 130SIGINT'in ölmesiyle aynı değildir (bazı mermiler her $?iki durumda da aynı değere ayarlanmış olsa da ), ancak SIGINT'in ölümünü bildirmek için kullanılır (SIGINT'in en fazla 2 olduğu sistemlerde).
Ancak bash, ksh93veya FreeBSD için shbu işe yaramaz. 130 çıkış durumunun SIGINT tarafından bir ölüm olarak görülmediği ve bir ebeveyn betiğinin iptal edilmeyeceği belirtildi .
Bu nedenle, muhtemelen daha iyi bir alternatif, SIGINT'i aldıktan sonra SIGINT ile kendimizi öldürmek olacaktır:
trap '
trap - INT # restore default INT handler
kill -s INT "$$"
' INT
for f in *.txt; do vi "$f"; cp "$f" newdir; done. Kullanıcı dosyalardan birini düzenlerken Ctrl + C tuşlarına basarsa,viyalnızca bir mesaj görüntüler. Kullanıcı dosyayı düzenlemeyi bitirdikten sonra döngünün devam etmesi makul görünüyor. (Ve evet, söyleyebileceğinizi biliyorumvi *.txt; cp *.txt newdir; sadecefordöngüyü örnek olarak sunuyorum .)