Saya mengerti sintaks subshell menjadi (<commands...>)
, apakah $()
hanya subkulit yang Anda dapat mengambil nilai variabel dari?
Catatan: Ini berlaku untuk bash 4.4 berdasarkan perbedaan kata dalam dokumentasinya.
Saya mengerti sintaks subshell menjadi (<commands...>)
, apakah $()
hanya subkulit yang Anda dapat mengambil nilai variabel dari?
Catatan: Ini berlaku untuk bash 4.4 berdasarkan perbedaan kata dalam dokumentasinya.
Jawaban:
$(…)
adalah subkulit menurut definisi: ini adalah salinan dari kondisi runtime shell¹, dan perubahan pada status yang dibuat dalam subkulit tidak memiliki dampak pada induk. Subkulit biasanya diimplementasikan dengan forking proses baru (tetapi beberapa shell dapat mengoptimalkan ini dalam beberapa kasus).
Itu bukan subkulit tempat Anda dapat mengambil nilai variabel. Jika perubahan variabel berdampak pada induk, itu tidak akan menjadi subkulit. Ini adalah subkulit yang outputnya dapat diambil orang tua. Subkulit yang dibuat oleh $(…)
memiliki output standar yang diatur ke pipa, dan induk membaca dari pipa itu dan mengumpulkan output.
Ada beberapa konstruksi lain yang membuat subkulit. Saya pikir ini adalah daftar lengkap untuk bash:
( … )
tidak melakukan apa-apa selain membuat subkulit dan menunggu itu berakhir). Kontras dengan { … }
perintah grup mana yang murni untuk tujuan sintaksis dan tidak membuat subkulit.… &
membuat subkulit dan tidak menunggu itu berakhir.… | …
membuat dua subkulit, satu untuk sisi kiri dan satu untuk sisi kanan, dan menunggu keduanya berakhir. Shell membuat pipa dan menghubungkan output standar sisi kiri ke ujung penulisan pipa dan input standar sisi kanan ke ujung read. Dalam beberapa shell (ksh88, ksh93, zsh, bash dengan set lastpipe
opsi dan efektif), sisi kanan berjalan di shell asli, sehingga konstruksi pipa hanya menciptakan satu subkulit.$(…)
(juga dieja `…`
) membuat subkulit dengan output standarnya disetel ke pipa, mengumpulkan output di induknya dan memperluas ke output itu, dikurangi garis turunya yang tertinggal. (Dan hasilnya mungkin lebih lanjut akan terpecah dan menggumpal, tapi itu cerita lain.)<(…)
membuat subkulit dengan output standar yang disetel ke pipa dan mengembang ke nama pipa. Induk (atau proses lain) dapat membuka pipa untuk berkomunikasi dengan subkulit. >(…)
melakukan hal yang sama tetapi dengan pipa pada input standar.coproc …
membuat subkulit dan tidak menunggu itu berakhir. Input dan output standar subkulit masing-masing diatur ke pipa dengan induk yang terhubung ke ujung masing-masing pipa.${...}
dalam jawabannya?
command | { read line; … }
(tergantung pada shell, line
mungkin atau mungkin tidak tersedia setelah pipa). Semua cara melibatkan subkulit karena perintah yang menghasilkan output harus berjalan secara independen dari shell yang membaca input. Jika perintah itu murni internal ke shell (hanya shell yang dibangun dan dibangun, tidak ada perintah eksternal), shell mungkin tidak membuat subproses, tapi itu hanya optimasi, itu masih membuat subkulit.
Dari halaman manual bash (1) di bash versi 4.4, bagian "EXPANSION", subbagian "Command Substitution":
Bash melakukan ekspansi dengan mengeksekusi
command
di lingkungan subkulit [...]
bash
manual tidak menyebutkan subshell: Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.
Saya ingin tahu apakah ini adalah penghilangan yang disengaja.