Tuzak bir alt kabuk tarafından miras alınır?


14

Aşağıdaki komut dosyasını denedim:

#!/bin/bash
trap 'echo "touching a file" && touch $FILE' EXIT

foo1(){
        echo "foo1"
}
foo(){
        echo "foo"
        export FILE=${FILE:-/tmp/file1}
}
(foo1)
foo

Yukarıdaki komut dosyasının çıktısı şöyleydi:

[root@usr1 my_tests]# ./test.sh
foo1
foo
touching a file

Ancak tuzağın da çıkışta çağrılmasını bekliyordum foo1, ki bu da alt kabukta denir.

  • Bu bekleniyor mu?
  • Is trapbir kabuktaki miras?
  • Evet ise, hangi durumda trapbir alt kabuk tarafından miras alınır?

Yanıtlar:


10

Tuzak işleyicileri asla alt kabuklar tarafından miras alınmaz. Bu POSIX tarafından belirtilir :

Alt kabuk girildiğinde, yok sayılmayan tuzaklar varsayılan eylemlere ayarlanır.

Yok sayılan sinyallerin ( trap '' SIGFOO) alt kabukta (ve kabuk tarafından başlatılan harici programlarda) yok sayıldığını unutmayın .


3
Bash set -Eiçinde alt kabukları tuzakları miras almak için yapabilirsiniz , ama doğru almak için gerçekten zor (en azından benim deneyim).
dragon788

Bunun tüm tuzaklar için işe yarayıp yaramadığını bilmiyorum. ERR için çalıştığını biliyorum
yosefrow

4

trapalt kabuklara dağıtılmaz, ancak bazı yollar alt kabuğun ana kabuğun tuzaklarını rapor etmesine izin verirken, diğerleri bunu yapmaz. Ben bash ile macos üzerinde bazı testler yaptım.

GNU bash, sürüm 4.4.12 (1) -çalışma (x86_64-apple-darwin16.3.0):

trap 'echo hello' EXIT
trap # trap -- 'echo hello' EXIT
echo "$(trap)" # trap -- 'echo hello' EXIT
trap | cat # trap -- 'echo hello' EXIT
(trap) | cat # trap -- 'echo hello' EXIT
cat < <(trap) # empty
cat <<< "$(trap)" # empty
bash -c 'trap' # empty
trap & # trap -- 'echo hello' EXIT

GNU bash, sürüm 3.2.57 (1) -çalışma (x86_64-apple-darwin16):

trap 'echo hello' EXIT
trap # trap -- 'echo hello' EXIT
echo "$(trap)" # trap -- 'echo hello' EXIT
trap > >(cat) # trap -- 'echo hello' EXIT
trap | cat # empty
(trap) | cat # empty
cat < <(trap) # empty
cat <<< "$(trap)" # empty
bash -c 'trap' # empty
trap & # empty

Bu trap_output="$(trap)"tuzak çıktı yakalamak için çalışacağını bilmek güzel . Eğer trap >trap_output_filebir dosya (fifo çalışmaz bash 3.2.57) çıktı ve daha sonra ile tekrar okumak için yapmak dışında işe yaramadı eğer bunu yapmak için başka bir yol düşünemiyorumtrap_output="$(<trap_output_file)"

fifo çalışmaz bash 3.2.57çünkü trap &boştur bash 3.2.57ama değilbash 4.4.12

GNU bash, sürüm 4.4.12 (1) -çalışma (x86_64-apple-darwin16.3.0):

mkfifo /tmp/fifo; trap >/tmp/fifo & trap_output=$(</tmp/fifo); rm -f /tmp/fifo; echo "$trap_output"
# trap -- 'echo hello' EXIT

mkfifo /tmp/fifo; trap_output=$(</tmp/fifo) & trap >/tmp/fifo; rm -f /tmp/fifo; echo "$trap_output"
# empty because trap_output=$(</tmp/fifo) sets the variable in a subshell

GNU bash, sürüm 3.2.57 (1) -çalışma (x86_64-apple-darwin16):

mkfifo /tmp/fifo; trap >/tmp/fifo & trap_output=$(</tmp/fifo); rm -f /tmp/fifo; echo "$trap_output"
# empty because trap >/tmp/fifo & is empty since it uses trap &

mkfifo /tmp/fifo; trap_output=$(</tmp/fifo) & trap >/tmp/fifo; rm -f /tmp/fifo; echo "$trap_output"
# empty because trap_output=$(</tmp/fifo) sets the variable in a subshell

2

trap tanımlar alt kabuklara yayılmaz.

Doğrulamak:

trap "echo bla" 1 2 3"

(trap)


2
Birçok kabuk (trap)özel bir durum olarak ele alınır , böylece alt kabuk ana kabuğun tuzaklarını rapor edebilir (ancak aslında kullanamaz). Böylece bu test her zaman güvenilir değildir.
JigglyNaga

Bourne Shell ile çalışır ve türevleri var: ksh88, bosh(Schily Bourne Shell) ve heirloom-sh. Haklısın: ksh93farklı davranıyor.
schily

Söz konusu komut dosyasının kullandığı bash'de çalışmaz.
JigglyNaga

Peki, bash'de çalışır : bashçağırırsanız hiçbir şey çıkarmaz (trap).
schily
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.