Perhatikan juga bahwa export name=valueitu tidak portabel. Bergantung pada apa yang Anda inginkan, cobalah name=value; export namesolusi portabel.
tripleee
Jawaban:
1054
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.
Secara khusus ekspor membuat variabel tersedia untuk proses anak melalui lingkungan.
Beano
15
Saya juga akan menambahkan bahwa jika ekspor ada dalam file yang Anda "sumber" (seperti nama file) maka itu ekspor ke lingkungan kerja Anda juga.
rogerdpack
6
@rogerdpack tidak bisakah Anda melakukannya tanpa ekspor? cat> blah \ na = hi \ n. bla; echo $ a; output 'hai' untuk saya.
David Winiecki
2
Bagus itu bekerja bahkan tanpa ekspor. Jadi saya kira ketika sumber file, jika Anda menggunakan ekspor itu akan tercermin dalam proses anak, jika Anda tidak itu hanya akan mempengaruhi lingkungan bash lokal ...
rogerdpack
19
Ada satu kasus tepi untuk ini; name=value commandtidak membuat variabel tersedia di sub-proses command.
Oliver Charlesworth
254
Untuk menggambarkan apa yang dikatakan jawaban lain:
Satu lagi contoh untuk inial$ foobar="Whatever" bash
Alun
70
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.
Perhatikan bahwa ini tidak sepenuhnya benar. Dalam 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.
William Pursell
7
Saya tidak yakin apa yang dashharus dilakukan dengan ini. Poster asli bertanya secara spesifik tentang bash.
Starfish
14
Pertanyaannya ditandai bashtetapi berlaku sama untuk varian bourne-shell. Menjadi terlalu spesifik dan memberikan jawaban yang hanya berlaku untuk bashadalah kejahatan besar.
William Pursell
12
bashadalah jQuery of the shell.
Potherca
2
export makes the variable available to subshells, and that is correctIni adalah penggunaan terminologi yang sangat membingungkan. Subshell tidak perlu exportmewarisi variabel. Subproses lakukan.
Amit Naidu
62
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 bashmuncul dalam naskah Anda).
Sub kerang akan memiliki akses ke semua variabel dari orangtua, terlepas dari negara mereka diekspor.
Sub proses hanya akan melihat variabel yang diekspor.
Apa yang umum dalam dua konstruksi ini adalah bahwa tidak ada yang dapat meneruskan variabel kembali ke shell induk.
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 execperintah, dan proses yang dimulai dengan metode ini juga tidak akan memiliki akses ke variabel yang tidak diekspor:
Perhatikan bahwa kita tidak melihat parent:garis kali ini, karena kita telah mengganti shell induk dengan execperintah, jadi tidak ada yang tersisa untuk mengeksekusi perintah itu.
Saya belum pernah melihat loop yang (dengan sendirinya) membuat subkulit; OTOH tidak seperti pipa (selalu untuk potongan selain yang terakhir, kadang-kadang untuk yang terakhir tergantung pada shell, versi, dan opsi Anda). Backgrounding ( &) juga membuat subkulit.
dave_thompson_085
Bagaimana dengan ini 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 $vartidak mencetak apa pun jika dijalankan pada baris kedua. Tapi satu berjajar var=asdf bash -c 'echo $var'; echo $varmemberi asdf\nasdf.
4xy
31
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, exporttandai 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
Subprocess1 has B=BobSubprocess2 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):
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.
Terima kasih, ini persis informasi yang saya cari karena saya melihat skrip yang menggunakan variabel lingkungan dan kemudian "diekspor kembali" mereka dengan nilai baru, dan saya bertanya-tanya apakah itu perlu.
Mike Lippert
8
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 exportada untuk.
exportadalah 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.
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.
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:
exportdigunakan untuk mengatur variabel lingkungan dalam sistem operasi. Variabel ini akan tersedia untuk semua proses anak yang dibuat oleh proses Bash saat ini selamanya.
Notasi variabel Bash (nama = nilai) digunakan untuk mengatur variabel lokal yang tersedia hanya untuk proses bash saat ini
Notasi variabel Bash, awalan perintah lain, menciptakan variabel lingkungan hanya untuk cakupan perintah itu.
bash vars tidak mendukung jenis sebanyak Python, tetapi memiliki string, integer, dan dua jenis array ('diindeks' / tradisional dan 'asosiatif' yang mirip dengan awk array, perl hash, atau Python dict). Kerang lain bervariasi; hanya string yang portabel .
dave_thompson_085
7
The jawaban yang diterima menyiratkan ini, tapi aku ingin membuat eksplisit koneksi ke builtin shell:
Seperti yang sudah disebutkan, exportakan membuat variabel tersedia untuk shell dan anak-anak. Jika exportini 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 processset| grep tango # prints tango=3 - "type set" shows `set` is a shell builtin
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 exportperintah 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.
Secara default, variabel yang dibuat dalam skrip hanya tersedia untuk shell saat ini; proses anak (sub-shell) tidak akan memiliki akses ke nilai yang telah ditetapkan atau dimodifikasi. Mengizinkan proses anak untuk melihat nilai-nilai, membutuhkan penggunaan perintah ekspor.
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.Jawaban:
export
membuat variabel tersedia untuk sub-proses.Itu adalah,
berarti bahwa nama variabel tersedia untuk setiap proses yang Anda jalankan dari proses shell itu. Jika Anda ingin suatu proses memanfaatkan variabel ini, gunakan
export
, dan jalankan proses dari shell itu.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.
sumber
name=value command
tidak membuat variabel tersedia di sub-prosescommand
.Untuk menggambarkan apa yang dikatakan jawaban lain:
sumber
al$ foobar="Whatever" bash
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)
atausetenv(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
.sumber
bash
, ekspor memang menambahkan variabel ke lingkungan shell saat ini, tetapi tidak demikian halnya dengandash
. Sepertinya saya bahwa menambahkan variabel ke lingkungan shell saat ini adalah cara paling sederhana untuk mengimplementasikan semantikexport
, tetapi perilaku itu tidak diamanatkan.dash
harus dilakukan dengan ini. Poster asli bertanya secara spesifik tentangbash
.bash
tetapi berlaku sama untuk varian bourne-shell. Menjadi terlalu spesifik dan memberikan jawaban yang hanya berlaku untukbash
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 perluexport
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 literalbash
muncul dalam naskah Anda).Apa yang umum dalam dua konstruksi ini adalah bahwa tidak ada yang dapat meneruskan variabel kembali ke shell induk.
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:Perhatikan bahwa kita tidak melihat
parent:
garis kali ini, karena kita telah mengganti shell induk denganexec
perintah, jadi tidak ada yang tersisa untuk mengeksekusi perintah itu.sumber
&
) juga membuat subkulit.var=asdf bash -c 'echo $var'
atauvar=asdf exec bash -c 'echo $var'
? Outputnya adalahasdf
. The;
membuat perbedaan jika ditempatkan setelah definisi variabel. Apa penjelasannya? Sepertinyavar
(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 berjajarvar=asdf bash -c 'echo $var'; echo $var
memberiasdf\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:
Hanya variabel yang diekspor (
B
) yang dilihat oleh subproses:Perubahan pada subproses tidak mengubah shell utama:
Variabel yang ditandai untuk ekspor memiliki nilai yang disalin ketika subproses dibuat:
Hanya variabel yang diekspor yang menjadi bagian dari lingkungan (
man environ
):Jadi, sekarang harus sejelas matahari musim panas! Terima kasih untuk Brain Agnew, alexp, dan William Prusell.
sumber
export
akan membuat variabel tersedia untuk semua shell yang bercabang dari shell saat ini.sumber
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.sumber
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:
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.sumber
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. Jikaexport
ini tidak digunakan, variabel hanya akan tersedia di shell, dan hanya shell builtin dapat mengaksesnya.Itu adalah,
sumber
Ini contoh lain:
Hanya dengan menggunakan ekspor VARTEST, nilai VARTEST tersedia di sudo bash -c '...'!
Untuk contoh lebih lanjut, lihat:
http://mywiki.wooledge.org/SubShell
bash-hackers.org/wiki/doku.php/scripting/processtree
sumber
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:sumber
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:
maka hanya $ OURNAME yang muncul di env. Variabel $ MYNAME tidak ada dalam env.
tetapi variabel $ MYNAME ada di shell
sumber
Secara default, variabel yang dibuat dalam skrip hanya tersedia untuk shell saat ini; proses anak (sub-shell) tidak akan memiliki akses ke nilai yang telah ditetapkan atau dimodifikasi. Mengizinkan proses anak untuk melihat nilai-nilai, membutuhkan penggunaan perintah ekspor.
sumber
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.
sumber