Apakah sub-shell sama dengan shell anak

11

Ada dua nama ini: subshell dan child-shell .

Ya, proses anak akan dimulai dengan semua ini:

sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat

Apakah semuanya sama dan berbagi nama yang sama? Apakah semua memiliki properti yang sama?


POSIX memiliki definisi ini :

Lingkungan eksekusi shell terdiri dari ....

Tetapi paragraf terakhir dari tautan di atas memiliki ini:

Lingkungan subkulit harus dibuat sebagai duplikat dari lingkungan shell, kecuali bahwa perangkap sinyal yang tidak diabaikan harus diatur ke tindakan default.

Dan khususnya:

Substitusi perintah, perintah yang dikelompokkan dengan tanda kurung, dan daftar asinkron harus dijalankan dalam lingkungan subkulit. Selain itu, setiap perintah pipa multi-perintah berada dalam lingkungan subkulit; ....

Tidak sh -c 'echo "Hello"'termasuk di sana, haruskah itu disebut subkulit juga?

Gilles 'SANGAT berhenti menjadi jahat'
sumber

Jawaban:

14

Subkulit menduplikasi shell yang ada. Ini memiliki variabel yang forksama¹, fungsi yang sama, opsi yang sama, dll. Di bawah tenda, sebuah subkulit dibuat dengan system call²; proses anak berlanjut untuk melakukan apa yang diharapkan darinya sementara orangtua menunggu (misalnya, $(…)) atau melanjutkan hidupnya (misalnya, … &) atau melakukan apa yang diharapkan darinya (misalnya, … | …).

sh -c …tidak membuat subkulit. Ini meluncurkan program lain. Program itu kebetulan shell, tapi itu hanya kebetulan. Program ini bahkan mungkin merupakan shell yang berbeda (misalnya, jika Anda menjalankan sh -c …dari bash, dan shdash), yaitu, program yang sama sekali berbeda yang kebetulan memiliki kesamaan yang signifikan dalam perilakunya. Di bawah tenda, meluncurkan perintah eksternal ( shatau lainnya) memanggil panggilan forksistem dan kemudian execvepanggilan sistem untuk mengganti program shell di subproses oleh program lain (di sini sh).

¹ Termasuk $$, tetapi mengecualikan beberapa variabel khusus-shell seperti bash dan mksh BASHPID.
² Setidaknya, itulah implementasi tradisional dan biasa. Kerang dapat mengoptimalkan garpu jika mereka dapat meniru perilaku sebaliknya.

Halaman manual yang relevan: fork (2) , execve (2) .

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Terima kasih. Apa yang menjalankan skrip bash dengan bash shebang?
Tim
@Tim Sama seperti sh -c: itu adalah subproses yang kebetulan merupakan shell.
Gilles 'SO- stop being evil'
(1) "meluncurkan perintah eksternal (sh atau yang lain) panggilan sistem panggilan garpu dan kemudian panggilan sistem eksekusi untuk mengganti program shell di subprocess oleh program lain (di sini dia)." Apakah benar bahwa garpu pertama kali membuat subkulit dan kemudian jalankan ganti subkulit dengan program eksternal? Jadi dalam dua kasus di balasan Anda, sebuah subkulit selalu dibuat? (2) "Subkulit yang menduplikasi shell yang ada." apa artinya?
Tim
(3) di bash -c <command>, setelah garpu shell dan kemudian mengeksekusi bash -c <command>, shell bash dibuat. Lalu apakah panggilan sistem digunakan untuk menjalankan <command>lagi garpu shell dan mengeksekusi <command>?
Tim
2
@cuonglm "Anak shell" bukan istilah teknis dengan makna tertentu, tidak seperti "subkulit". Jika itu adalah shell yang merupakan anak, maka itu adalah shell anak, mengikuti aturan bahasa Inggris yang biasa.
Gilles 'SANGAT berhenti menjadi jahat'
1

Lingkungan sub-shell tidak perlu hidup dalam proses terpisah, hanya perlu menduplikasi lingkungan eksekusi saat ini. Dalam ksh93hal ini dilakukan oleh virtual sub-shellmekanisme yang tidak memanggil fork(). Ini membuat ksh93 sangat cepat pada platform kuno seperti Win-DOS, karena Win-DOSsangat lambat dengan forking.

sh -c cmd di sisi lain membuat proses baru dengan shell default yang tidak harus sama dengan shell interaktif Anda saat ini.

Bahkan ketika shdan shell Anda saat ini identik, ini tidak menduplikasi lingkungan eksekusi dan dengan demikian tidak membuat sub-shell.

schily
sumber
Jadi, di shell lain kecuali ksh93, subshell adalah shell anak kan?
cuonglm
Saya tahu tidak ada implementasi lain yang mengimplementasikan subshell virtual saat ini.
schily