Buku Bash Pembelajaran menyebutkan bahwa subkulit hanya akan mewarisi variabel lingkungan dan deskriptor file, dll., dan tidak akan mewarisi variabel yang tidak diekspor:
$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var
$
Seperti yang saya tahu shell akan membuat dua subkulit untuk ()
dan untuk ./file
, tapi mengapa di ()
kasus apakah subkulit mengidentifikasi var
variabel meskipun tidak diekspor dan dalam ./file
kasus itu tidak mengidentifikasinya?
# Strace for ()
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25617
# Strace for ./file
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25631
Saya mencoba menggunakan strace
untuk mengetahui bagaimana ini terjadi dan secara mengejutkan saya menemukan bahwa bash akan menggunakan argumen yang sama untuk panggilan sistem klon, jadi ini berarti bahwa kedua proses bercabang di ()
dan ./file
harus memiliki ruang alamat proses yang sama dengan induknya, jadi mengapa di ()
case adalah variabel yang terlihat oleh subkulit dan hal yang sama tidak terjadi untuk ./file
kasus, meskipun argumen yang sama didasarkan pada panggilan sistem klon?
Jawaban yang Diterima:
Buku Bash Pembelajaran salah. Subkulit mewarisi semua variabel. Bahkan $$
(PID dari shell asli) disimpan. Alasannya adalah karena untuk subkulit, shell hanya bercabang dan tidak mengeksekusi shell baru (sebaliknya, saat Anda mengetik ./file
, perintah baru dijalankan, mis. cangkang baru; di strace output, lihat execve
dan serupa). Jadi, pada dasarnya, ini hanya salinan (dengan beberapa perbedaan yang terdokumentasi).
Catatan:ini tidak khusus untuk bash; ini berlaku untuk shell apa pun.