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=1
set -a
:Memberi tahu shell untuk memasukkan nama apa pun yang disetel ke lingkungan. Seperti meletakkanexport
sebelum setiap penugasan. Berguna untuk.env
file, 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,env
hanya 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.