Perbedaan antara variabel shell yang diekspor dan yang tidak dalam bash

41

Bash tampaknya membedakan antara variabel yang telah diekspor dan yang tidak.

contoh:

$ FOO=BAR
$ env | grep FOO
$ set | grep FOO
FOO=BAR

setmelihat variabel tetapi envtidak.

$ export BAR=FOO
$ env | grep FOO
BAR=FOO
$ set | grep FOO
BAR=FOO
FOO=BAR

setmelihat kedua variabel tetapi envhanya melihat variabel yang diekspor.

Saya tahu itu setbash builtin dan envtidak.

Apa perbedaan antara variabel yang diekspor dan yang tidak?

lesmana
sumber
17
Catatan terminologi: "variabel lingkungan" selalu diekspor. Variabel yang tidak diekspor adalah “variabel shell” (atau “parameter”).
Gilles 'SO- stop being evil'

Jawaban:

44

Variabel yang diekspor dibawa ke lingkungan perintah yang dijalankan oleh shell yang mengekspornya, sementara variabel yang tidak diekspor adalah lokal untuk permintaan shell saat ini. Dari exporthalaman manual:

Shell harus memberikan atribut ekspor ke variabel yang sesuai dengan nama yang ditentukan, yang akan menyebabkan mereka berada di lingkungan perintah yang dieksekusi selanjutnya.

setmenampilkan lingkungan saat ini, yang mencakup variabel lokal yang tidak diekspor. envdigunakan untuk meluncurkan program di lingkungan baru, dan tanpa argumen akan menghasilkan seperti apa lingkungan baru itu. Karena envmenciptakan lingkungan baru, hanya variabel yang diekspor yang dimasukkan, seperti halnya untuk setiap program yang diluncurkan dari shell itu. Misalnya, memunculkan shell kedua di dalam shell pertama (saya dulu $$mewakili prompt di shell bagian dalam):

$ FOO=BAR
$ bash
$$ echo $FOO             # Note the empty line

$$ exit
$ export FOO
$ bash
$$ echo $FOO
BAR
$$

Perhatikan bahwa itu adalah variabel yang diekspor, bukan hanya nilainya. Ini berarti bahwa sekali Anda export FOO, FOOmenjadi variabel global dan muncul di lingkungan berikutnya, bahkan jika diubah kemudian:

$ export FOO
$ FOO=BAR
$ bash
$$ echo $FOO
BAR
$$
Michael Mrozek
sumber
jadi jika Anda hanya khawatir tentang shell saat ini, apakah Anda perlu mengekspor? Secara terpisah, mengapa localeshell saat ini tidak menampilkan pembaruan?
Pacerier