Subkulit dimulai sebagai salinan hampir identik dari proses shell asli. Di bawah tenda, shell memanggil forksystem call 1 , yang menciptakan proses baru yang kode dan memorinya adalah salinan 2 . Ketika subkulit dibuat, ada sangat sedikit perbedaan antara itu dan induknya. Secara khusus, mereka memiliki variabel yang sama. Bahkan $$variabel khusus menyimpan nilai yang sama dalam subkulit: ini adalah ID proses shell asli. Demikian pula $PPIDPID induk dari shell asli.
Beberapa shell mengubah beberapa variabel dalam subkulit. Bash mengatur BASHPIDke PID dari proses shell, yang berubah dalam subshell. Bash, zsh dan mksh mengatur untuk $RANDOMmenghasilkan nilai yang berbeda di induk dan di subkulit. Namun terlepas dari kasus khusus bawaan seperti ini, semua variabel memiliki nilai yang sama dalam subkulit seperti pada shell asli, status ekspor yang sama, status hanya baca yang sama, dll. Semua definisi fungsi, alias definisi, opsi shell dan pengaturan lain juga diwarisi.
Subkulit yang dibuat oleh (…)memiliki deskriptor file yang sama dengan pembuatnya. Beberapa cara lain untuk membuat subkulit memodifikasi beberapa deskriptor file sebelum mengeksekusi kode pengguna; misalnya, sisi kiri pipa berjalan dalam subkulit 3 dengan output standar yang terhubung ke pipa. Subkulit juga dimulai dengan direktori saat ini yang sama, masker sinyal yang sama, dll. Salah satu dari beberapa pengecualian adalah bahwa subkulit tidak mewarisi jebakan khusus: sinyal yang diabaikan ( ) tetap diabaikan dalam subkulit, tetapi jebakan lain ( SIGNAL ) diatur ulang ke tindakan standar 4 .trap '' SIGNALtrap CODE
Subshell berbeda dari mengeksekusi skrip. Sebuah skrip adalah program terpisah. Program terpisah ini mungkin secara kebetulan juga merupakan skrip yang dijalankan oleh penerjemah yang sama dengan induknya, tetapi kebetulan ini tidak memberikan program terpisah visibilitas khusus pada data internal induk. Variabel yang tidak diekspor adalah data internal, jadi ketika interpreter untuk skrip shell anak dieksekusi , ia tidak melihat variabel-variabel ini. Variabel yang diekspor, yaitu variabel lingkungan, ditransmisikan ke program yang dijalankan.
Jadi:
x=1
(echo $x)
dicetak 1karena subkulit adalah replikasi dari shell yang memunculkannya.
x=1
sh -c 'echo $x'
kebetulan menjalankan shell sebagai proses anak dari shell, tetapi xpada baris kedua tidak memiliki lebih banyak koneksi dengan xpada baris kedua daripada di
x=1
perl -le 'print $x'
atau
x=1
python -c 'print x'
1 Pengecualian adalah ksh93shell di mana forking dioptimalkan keluar dan sebagian besar efek sampingnya ditiru.
2 Semantik, itu salinan. Dari perspektif implementasi, ada banyak sharing yang terjadi.
3 Untuk sisi kanan, tergantung pada cangkangnya.
4 Jika Anda menguji ini, perhatikan bahwa hal-hal seperti$(trap) dapat melaporkan jebakan dari shell asli. Perhatikan juga bahwa banyak cangkang memiliki bug dalam kasus sudut yang melibatkan jebakan. Misalnya ninjalj mencatat bahwa pada bash 4.3, bash -x -c 'trap "echo ERR at \$BASH_SUBSHELL \$BASHPID" ERR; set -E; false; echo one subshell; (false); echo two subshells; ( (false) )'menjalankan ERRjebakan dari subkulit bersarang dalam kasus "dua subkulit", tetapi bukan ERRjebakan dari subkulit perantara - set -Eopsi harus menyebarkanERRjebakan ke semua subkulit tetapi subkulit perantara dioptimalkan dan jadi tidak ada untuk menjalankan ERRjebakannya.
x=out; (x=in; echo $x))