Saya membaca di sini bahwa tujuan export di shell adalah membuat variabel tersedia untuk sub-proses yang dimulai dari shell.
Namun, saya juga membaca di sini dan di sini bahwa “Proses mewarisi lingkungannya dari induknya (proses yang memulainya).”
Jika demikian, mengapa kita perlu export ? Apa yang saya lewatkan?
Apakah variabel shell bukan bagian dari lingkungan secara default? Apa bedanya?
Jawaban yang Diterima:
Asumsi Anda adalah bahwa variabel shell di lingkungan . Ini tidak benar. export perintah adalah apa yang mendefinisikan nama berada di lingkungan sama sekali. Jadi:
a=1 b=2
export b
menghasilkan shell . saat ini mengetahui bahwa $a diperluas ke 1 dan $b ke 2, tetapi subproses tidak akan tahu apa-apa tentang a karena itu bukan bagian dari lingkungan (bahkan di shell saat ini).
Beberapa alat yang berguna:
set:Berguna untuk melihat parameter shell saat ini, diekspor atau tidakset -k:Menetapkan argumen yang ditetapkan di lingkungan. Pertimbangkanf() { set -k; env; }; f a=1set -a:Memberi tahu shell untuk memasukkan nama apa pun yang disetel ke lingkungan. Seperti meletakkanexportsebelum setiap penugasan. Berguna untuk.envfile, seperti dalamset -a; . .env; set +a.export:Memberitahu shell untuk memberi nama di lingkungan. Ekspor dan penugasan adalah dua operasi yang sama sekali berbeda.env:Sebagai perintah eksternal,envhanya dapat memberi tahu Anda tentang diwariskan lingkungan, sehingga berguna untuk pemeriksaan kewarasan.env -i:Berguna untuk membersihkan lingkungan sebelum memulai subproses.
Alternatif untuk export :
name=val command# Tugas sebelum perintah mengekspor nama itu ke perintah.declare/local -x name# Mengekspor nama, khususnya berguna dalam fungsi shell ketika Anda ingin menghindari mengekspos nama ke luar lingkup.set -a# Ekspor setiap tugas berikut.
Motivasi
Jadi mengapa shell perlu memiliki variabel sendiri dan dan lingkungan yang berbeda? Saya yakin ada beberapa alasan historis, tetapi saya pikir alasan utamanya adalah pelingkupan. Lingkungan adalah untuk subproses, tetapi ada banyak operasi yang dapat Anda lakukan di shell tanpa memotong subproses. Misalkan Anda mengulang:
for i in {0..50}; do
somecommand
done
Mengapa membuang-buang memori untuk somecommand dengan memasukkan i , membuat lingkungannya lebih besar dari yang seharusnya? Bagaimana jika nama variabel yang Anda pilih di shell kebetulan berarti sesuatu yang tidak diinginkan oleh program? (Favorit pribadi saya termasuk DEBUG dan VERBOSE . Nama-nama itu digunakan di mana-mana dan jarang ada ruang nama yang memadai.)
Apa lingkungan jika bukan shell?
Terkadang untuk memahami perilaku Unix Anda harus melihat syscalls, API dasar untuk berinteraksi dengan kernel dan OS. Di sini, kita melihat exec keluarga panggilan, yang digunakan shell saat membuat subproses. Berikut kutipan dari halaman manual untuk exec(3) (penekanan pada saya):
execle()danexecvpe()fungsi memungkinkan pemanggil untuk menentukan lingkungan program yang dijalankan melalui argumen envp. Argumen envp adalah larik pointer ke string yang diakhiri null dan harus diakhiri dengan pointer NULL. Fungsi lain mengambil lingkungan untuk gambar proses baru dari lingkungan variabel eksternal dalam proses pemanggilan.
Jadi tulis export somename di shell akan sama dengan menyalin nama ke kamus global environ di C. Tetapi menetapkan somename tanpa mengekspornya akan seperti menugaskannya di C, tanpa menyalinnya ke environ variabel.