Subshell standar vs subshell perintah-substitusi

8

Tolong jelaskan output perangkap ini:

$ line(){ echo -------------; echo $BASHPID; }
$ trap 'echo bye' EXIT; trap -p; line; (trap -p; line); echo "$(trap -p; line)"

trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6176
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6178
trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6180

Mengapa subshell perintah-substitusi berperilaku berbeda karena mengklaim mewarisi disposisi perangkap (kecuali bahwa itu sebenarnya tidak mengikuti mereka)?

PSkocik
sumber

Jawaban:

2

Menarik. Ini tampaknya merupakan perilaku spesifik-Bash.

Saya mencoba 3 kerang yang kompatibel dengan POSIX lainnya (zsh, dash, busybox), dan semuanya echo "$(trap)"memberikan hasil yang sama seperti (trap): subshell dijalankan, dan subshell tidak menunjukkan EXITjebakan.

(Catatan yang trap -pkhusus untuk Bash, dan tanpa parameter tambahan itu melakukan hal yang sama seperti traptanpa parameter.)

Perilaku Bash berpotensi berguna : itu artinya Anda dapat menulis a="$(trap)"untuk mengambil pengaturan perangkap dari shell induk, yang lebih cenderung menarik.

Namun, jika Anda mengatur atau menghapus jebakan dalam subkulit, maka itu akan mencantumkan perangkap subkulit sebagai ganti dari induknya:

$ trap 'echo bye' EXIT
$ echo "$(trap TERM; trap)"  # explicitly clear TERM, but leave EXIT alone
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

Jadi mereka juga telah membahas kasus langka di mana Anda tertarik pada jebakan subkulit.

Secara umum, saya perhatikan bahwa pengembang Bash tampaknya telah melakukan upaya ekstra untuk membuat penanganan subshell berfungsi dengan baik. Ini juga jauh lebih mudah untuk mengelola subproses latar belakang dengan Bash daripada dengan shell POSIX yang lebih minimal.

Jander
sumber