Ne olur hem olmasıdır bash
ve ping
SIGINT almak ( bash
varlık değil interaktif, hem ping
ve bash
bunu 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, bash
SIGINT'in eşzamansız olarak, yalnızca o anda çalışan komuttan çıktıktan sonra ilgilenir. bash
sadece 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.sh
sleep
sh
bash
ping
En 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ığı bash
bastığınız ettik notlar Ctrl-C
ama onun SIGINT işleyicilerindeki beri ping
normalde çıkışlar, bash
çıkış vermez.
Eğer sleep 1
bu döngüye bir giriş ekler ve Ctrl-C
çalışırken basın sleep
, çünkü sleep
SIGINT üzerinde özel bir işleyicisi yoktur, ölecek ve bash
SIGINT'ten öldüğünü bash
bildirecek ve bu durumda çıkacak (aslında SIGINT ile kendini öldürecek. kesintiyi ebeveyne bildirmek için).
Neden bash
böyle davrandığına gelince , emin değilim ve davranışların her zaman belirleyici olmadığını not ediyorum. Ben sadece sordunuz üzerinde soru bash
geliş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.
bash
Yukarı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
bash
Bir 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 bash
komut dosyası da kesilir). Bir exit 130
SIGINT'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
, ksh93
veya FreeBSD için sh
bu 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,vi
yalnı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
; sadecefor
döngüyü örnek olarak sunuyorum .)