Jawaban:
export
membuat variabel tersedia untuk sub-proses.
Itu adalah,
export name=value
berarti bahwa nama variabel tersedia untuk setiap proses yang Anda jalankan dari proses shell itu. Jika Anda ingin suatu proses memanfaatkan variabel ini, gunakanexport
, dan jalankan proses dari shell itu.
name=value
berarti ruang lingkup variabel dibatasi untuk shell, dan tidak tersedia untuk proses lain. Anda akan menggunakan ini untuk (katakanlah) variabel loop, variabel sementara dll.
Penting untuk dicatat bahwa mengekspor variabel tidak membuatnya tersedia untuk proses induk. Artinya, menentukan dan mengekspor variabel dalam proses spawned tidak membuatnya tersedia dalam proses yang diluncurkan itu.
name=value command
tidak membuat variabel tersedia di sub-proses command
.
Yang lain telah menjawab bahwa ekspor membuat variabel tersedia untuk subkulit, dan itu benar tetapi hanya efek samping. Ketika Anda mengekspor variabel, itu menempatkan variabel itu di lingkungan shell saat ini (yaitu shell panggilan putenv(3)
atau setenv(3)
).
Lingkungan suatu proses diwariskan di eksekutif, membuat variabel terlihat dalam subkulit.
Sunting (dengan perspektif 5 tahun): ini adalah jawaban konyol. Tujuan dari 'ekspor' adalah untuk membuat variabel "berada di lingkungan perintah yang dieksekusi selanjutnya", apakah perintah itu adalah subkulit atau subproses. Implementasi yang naif adalah dengan hanya menempatkan variabel di lingkungan shell, tetapi ini akan membuatnya tidak mungkin untuk diimplementasikan export -p
.
bash
, ekspor memang menambahkan variabel ke lingkungan shell saat ini, tetapi tidak demikian halnya dengan dash
. Sepertinya saya bahwa menambahkan variabel ke lingkungan shell saat ini adalah cara paling sederhana untuk mengimplementasikan semantik export
, tetapi perilaku itu tidak diamanatkan.
dash
harus dilakukan dengan ini. Poster asli bertanya secara spesifik tentang bash
.
bash
tetapi berlaku sama untuk varian bourne-shell. Menjadi terlalu spesifik dan memberikan jawaban yang hanya berlaku untuk bash
adalah kejahatan besar.
bash
adalah jQuery of the shell.
export makes the variable available to subshells, and that is correct
Ini adalah penggunaan terminologi yang sangat membingungkan. Subshell tidak perlu export
mewarisi variabel. Subproses lakukan.
Dikatakan bahwa tidak perlu untuk mengekspor dalam bash ketika menelurkan subkulit, sementara yang lain mengatakan sebaliknya. Hal ini penting untuk dicatat perbedaan antara subkulit (orang-orang yang diciptakan oleh ()
, ``
, $()
atau loop) dan subproses (proses yang dipanggil dengan nama, misalnya literal bash
muncul dalam naskah Anda).
Apa yang umum dalam dua konstruksi ini adalah bahwa tidak ada yang dapat meneruskan variabel kembali ke shell induk.
$ noexport=noexport; export export=export; (echo subshell: $noexport $export; subshell=subshell); bash -c 'echo subprocess: $noexport $export; subprocess=subprocess'; echo parent: $subshell $subprocess
subshell: noexport export
subprocess: export
parent:
Ada satu lagi sumber kebingungan: beberapa orang berpikir bahwa subproses 'bercabang' adalah yang tidak melihat variabel yang tidak diekspor. Biasanya fork () langsung diikuti oleh exec (), dan karena itulah tampaknya fork () adalah hal yang harus dicari, padahal sebenarnya itu adalah exec (). Anda dapat menjalankan perintah tanpa fork () terlebih dahulu dengan exec
perintah, dan proses yang dimulai dengan metode ini juga tidak akan memiliki akses ke variabel yang tidak diekspor:
$ noexport=noexport; export export=export; exec bash -c 'echo execd process: $noexport $export; execd=execd'; echo parent: $execd
execd process: export
Perhatikan bahwa kita tidak melihat parent:
garis kali ini, karena kita telah mengganti shell induk dengan exec
perintah, jadi tidak ada yang tersisa untuk mengeksekusi perintah itu.
&
) juga membuat subkulit.
var=asdf bash -c 'echo $var'
atau var=asdf exec bash -c 'echo $var'
? Outputnya adalah asdf
. The ;
membuat perbedaan jika ditempatkan setelah definisi variabel. Apa penjelasannya? Sepertinya var
(tanpa ;
) salam untuk menelurkan subproses entah bagaimana, karena shell asal tidak ada hubungannya dengan itu. echo $var
tidak mencetak apa pun jika dijalankan pada baris kedua. Tapi satu berjajar var=asdf bash -c 'echo $var'; echo $var
memberi asdf\nasdf
.
export NAME=value
untuk pengaturan dan variabel yang memiliki arti ke suatu subproses.
NAME=value
untuk variabel sementara atau loop pribadi ke proses shell saat ini.
Secara lebih rinci, export
tandai nama variabel di lingkungan yang menyalin ke subproses dan subproses mereka saat pembuatan. Tidak ada nama atau nilai yang pernah disalin kembali dari subproses.
Kesalahan umum adalah menempatkan spasi di sekitar tanda sama dengan:
$ export FOO = "bar"
bash: export: `=': not a valid identifier
Hanya variabel yang diekspor ( B
) yang dilihat oleh subproses:
$ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B" | bash
A is . B is Bob
Perubahan pada subproses tidak mengubah shell utama:
$ export B="Bob"; echo 'B="Banana"' | bash; echo $B
Bob
Variabel yang ditandai untuk ekspor memiliki nilai yang disalin ketika subproses dibuat:
$ export B="Bob"; echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash &
[1] 3306
$ B="Banana"; echo '(sleep 30; echo "Subprocess 2 has B=$B")' | bash
Subprocess 1 has B=Bob
Subprocess 2 has B=Banana
[1]+ Done echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash
Hanya variabel yang diekspor yang menjadi bagian dari lingkungan ( man environ
):
$ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB"
BOB=Bob
Jadi, sekarang harus sejelas matahari musim panas! Terima kasih untuk Brain Agnew, alexp, dan William Prusell.
Perlu dicatat bahwa Anda dapat mengekspor variabel dan kemudian mengubah nilainya. Nilai variabel yang berubah akan tersedia untuk proses anak. Setelah ekspor ditetapkan untuk variabel, Anda harus melakukan export -n <var>
untuk menghapus properti.
$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset
Seperti yang mungkin sudah Anda ketahui, UNIX memungkinkan proses untuk memiliki satu set variabel lingkungan, yang merupakan pasangan kunci / nilai, baik kunci dan nilai menjadi string. Sistem operasi bertanggung jawab untuk menjaga pasangan ini untuk setiap proses secara terpisah.
Program dapat mengakses variabel lingkungannya melalui API UNIX ini:
char *getenv(const char *name);
int setenv(const char *name, const char *value, int override);
int unsetenv(const char *name);
Proses juga mewarisi variabel lingkungan dari proses induk. Sistem operasi bertanggung jawab untuk membuat salinan dari semua "envars" pada saat proses anak dibuat.
Bash , di antara shell lainnya, mampu mengatur variabel lingkungannya berdasarkan permintaan pengguna. Inilah yang export
ada untuk.
export
adalah perintah Bash untuk mengatur variabel lingkungan untuk Bash. Semua variabel yang diatur dengan perintah ini akan diwarisi oleh semua proses yang akan dibuat oleh Bash ini.
Lebih lanjut tentang Lingkungan di Bash
Jenis variabel lain dalam Bash adalah variabel internal. Karena Bash bukan hanya shell interaktif, ia sebenarnya adalah juru bahasa skrip, seperti juru bahasa lain (misalnya Python) yang mampu menyimpan serangkaian variabelnya sendiri. Harus disebutkan bahwa Bash (tidak seperti Python) hanya mendukung variabel string.
Notasi untuk mendefinisikan variabel Bash adalah name=value
. Variabel-variabel ini tetap berada di dalam Bash dan tidak ada hubungannya dengan variabel lingkungan yang disimpan oleh sistem operasi.
Lebih lanjut tentang Parameter Shell (termasuk variabel)
Juga patut dicatat bahwa, menurut manual referensi Bash:
Lingkungan untuk setiap perintah atau fungsi sederhana dapat ditambah sementara dengan mengawalinya dengan penetapan parameter, seperti yang dijelaskan dalam Parameter Shell . Pernyataan penugasan ini hanya memengaruhi lingkungan yang dilihat oleh perintah itu.
Singkatnya:
export
digunakan untuk mengatur variabel lingkungan dalam sistem operasi. Variabel ini akan tersedia untuk semua proses anak yang dibuat oleh proses Bash saat ini selamanya.The jawaban yang diterima menyiratkan ini, tapi aku ingin membuat eksplisit koneksi ke builtin shell:
Seperti yang sudah disebutkan, export
akan membuat variabel tersedia untuk shell dan anak-anak. Jika export
ini tidak digunakan, variabel hanya akan tersedia di shell, dan hanya shell builtin dapat mengaksesnya.
Itu adalah,
tango=3
env | grep tango # prints nothing, since env is a child process
set | grep tango # prints tango=3 - "type set" shows `set` is a shell builtin
Ini contoh lain:
VARTEST="value of VARTEST"
#export VARTEST="value of VARTEST"
sudo env | grep -i vartest
sudo echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"
sudo bash -c 'echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"'
Hanya dengan menggunakan ekspor VARTEST, nilai VARTEST tersedia di sudo bash -c '...'!
Untuk contoh lebih lanjut, lihat:
bash-hackers.org/wiki/doku.php/scripting/processtree
Dua pencipta UNIX, Brian Kernighan dan Rob Pike, menjelaskan hal ini dalam buku mereka "Lingkungan Pemrograman UNIX". Google untuk judul dan Anda akan dengan mudah menemukan versi pdf.
Mereka membahas variabel shell di bagian 3.6, dan fokus pada penggunaan export
perintah di akhir bagian itu:
Ketika Anda ingin membuat nilai variabel dapat diakses di sub-shell, perintah ekspor shell harus digunakan. (Anda mungkin berpikir mengapa tidak ada cara untuk mengekspor nilai variabel dari sub-shell ke induknya).
Hanya untuk menunjukkan perbedaan antara variabel yang diekspor berada di lingkungan (env) dan variabel yang tidak diekspor yang tidak berada di lingkungan:
Jika saya melakukan ini:
$ MYNAME=Fred
$ export OURNAME=Jim
maka hanya $ OURNAME yang muncul di env. Variabel $ MYNAME tidak ada dalam env.
$ env | grep NAME
OURNAME=Jim
tetapi variabel $ MYNAME ada di shell
$ echo $MYNAME
Fred
Meskipun tidak secara eksplisit disebutkan dalam diskusi, TIDAK perlu menggunakan ekspor ketika memunculkan subkulit dari dalam bash karena semua variabel disalin ke dalam proses anak.
export name=value
itu tidak portabel. Bergantung pada apa yang Anda inginkan, cobalahname=value; export name
solusi portabel.