Saya hanya mengalami masalah yang menunjukkan bahwa saya tidak jelas tentang cakupan variabel shell.
Saya mencoba menggunakan bundle install
, yang merupakan perintah Ruby yang menggunakan nilai $GEM_HOME
untuk melakukan tugasnya. Saya telah menetapkan $GEM_HOME
, tetapi perintah mengabaikan nilai itu sampai saya gunakan export
, seperti pada export GEM_HOME=/some/path
.
Saya membaca bahwa ini membuat variabel entah bagaimana "global" (juga dikenal sebagai variabel lingkungan ), tetapi saya tidak mengerti apa artinya itu. Saya tahu tentang global dalam pemrograman, tetapi tidak lintas program yang berbeda.
Juga, mengingat bahwa pengaturan saya, variabel tersebut hanya berlaku untuk sesi shell saat ini, bagaimana saya mengaturnya untuk, katakanlah, proses yang dianemonisasi?
Cakupan apa yang bisa dimiliki oleh variabel shell?
sumber
FOO=bar
, itu menetapkan nilai untuk proses shell saat ini. Jika saya kemudian menjalankan program like (bundle install
), itu menciptakan proses anak, yang tidak mendapatkan aksesFOO
. Tetapi jika saya katakanexport FOO=bar
, proses anak (dan turunannya) akan memiliki akses ke sana. Salah satu dari mereka dapat, pada gilirannya, memintaexport FOO=buzz
untuk mengubah nilai bagi keturunannya, atau hanyaFOO=buzz
mengubah nilai hanya untuk dirinya sendiri. Apakah itu benar?Setidaknya di bawah
ksh
danbash
, variabel dapat memiliki tiga cakupan, bukan dua seperti semua jawaban yang tersisa mengatakan.Selain variabel yang diekspor (yaitu lingkungan) dan lingkup variabel shell yang tidak diekspor, ada juga yang lebih sempit ketiga untuk variabel fungsi lokal.
Variabel yang dideklarasikan dalam fungsi shell dengan
typeset
token hanya terlihat di dalam fungsi yang dideklarasikan di dalam dan di dalam (sub) fungsi yang dipanggil dari sana.Ini
ksh
/bash
kode:menghasilkan output ini:
Seperti yang Anda lihat, variabel yang diekspor ditampilkan dari tiga lokasi pertama, variabel yang tidak diekspor tidak ditampilkan di luar shell saat ini dan variabel fungsi lokal tidak memiliki nilai di luar fungsi itu sendiri. Tes terakhir tidak menunjukkan nilai sama sekali, ini karena variabel yang diekspor tidak dibagi di antara shell, yaitu mereka hanya bisa diwarisi dan nilai yang diwarisi tidak dapat dipengaruhi setelahnya oleh shell induk.
Perhatikan bahwa perilaku yang terakhir ini sangat berbeda dari Windows di mana Anda dapat menggunakan Variabel Sistem yang sepenuhnya global dan dibagikan oleh semua proses.
sumber
Mereka dicakup oleh proses
Penjawab lain membantu saya untuk memahami bahwa ruang lingkup variabel shell adalah tentang proses dan turunannya .
Ketika Anda mengetik perintah seperti
ls
pada baris perintah, Anda sebenarnya sedang forking proses untuk menjalankanls
program. Proses baru memiliki shell Anda sebagai induknya.Setiap proses dapat memiliki variabel "lokal" sendiri, yang tidak diteruskan ke proses anak. Itu juga dapat mengatur variabel "lingkungan", yang. Menggunakan
export
menciptakan variabel lingkungan. Dalam kedua kasus tersebut, proses yang tidak terkait (rekan asli) tidak akan melihat variabel; kita hanya mengendalikan apa yang dilihat oleh proses anak.Misalkan Anda memiliki bash shell, yang akan kita panggil A. Anda mengetik
bash
, yang membuat shell proses bash anak, yang akan kami panggil B. Apa pun yang Anda panggilexport
di A masih akan diatur dalam B.Sekarang, di B, katamu
FOO=b
. Satu dari dua hal akan terjadi:FOO
, itu akan membuat variabel lokal. Anak-anak B tidak akan mendapatkannya (kecuali B memanggilexport
).FOO
, ia akan memodifikasinya untuk dirinya sendiri dan selanjutnya anak-anak yang bercabang dua . Anak-anak B akan melihat nilai yang diberikan B. Namun, ini tidak akan memengaruhi A sama sekali.Ini demo cepat.
Semua ini menjelaskan masalah asli saya: Saya mengatur
GEM_HOME
di shell saya, tetapi ketika saya meneleponbundle install
, itu menciptakan proses anak. Karena saya belum pernah menggunakanexport
, proses anak tidak menerima cangkangGEM_HOME
.Tidak mengekspor
Anda dapat "membatalkan ekspor" suatu variabel - mencegahnya diteruskan ke anak-anak - dengan menggunakan
export -n FOO
.sumber
Penjelasan terbaik yang dapat saya temukan tentang ekspor adalah yang ini:
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html
Set variabel dalam subkulit atau kulit anak hanya terlihat oleh subkulit di mana ia didefinisikan. Variabel yang diekspor sebenarnya dibuat menjadi variabel lingkungan. Jadi untuk menjadi jelas Anda
bundle install
menjalankan shell sendiri yang tidak melihat$GEM_HOME
kecuali dibuatenvironment
variabel alias diekspor.Anda dapat melihat dokumentasi untuk ruang lingkup variabel di sini:
http://www.tldp.org/LDP/abs/html/subshells.html
sumber
FOO=bar
; Anda harus menggunakannyaexport
untuk membuatnya. Pertanyaan diperbaiki sesuai.Ada hierarki cakupan variabel, seperti yang diharapkan.
Lingkungan Hidup
Lingkup terluar adalah lingkungan. Ini adalah satu-satunya ruang lingkup yang dikelola oleh sistem operasi dan karenanya dijamin ada untuk setiap proses. Ketika suatu proses dimulai, ia menerima salinan lingkungan orang tuanya setelah itu keduanya menjadi independen: memodifikasi lingkungan anak tidak mengubah orangtua, dan memodifikasi lingkungan orangtua tidak mengubah lingkungan anak yang sudah ada.
Variabel shell
Kerang memiliki gagasan variabel mereka sendiri. Di sinilah segalanya mulai menjadi sedikit membingungkan.
Saat Anda menetapkan nilai ke variabel di shell, dan variabel itu sudah ada di lingkungan, variabel lingkungan menerima nilai baru. Namun jika variabel tersebut tidak ada di lingkungan namun itu menjadi variabel shell . Variabel Shell hanya ada dalam proses shell, mirip dengan bagaimana variabel Ruby hanya ada dalam skrip Ruby. Mereka tidak pernah diwarisi oleh proses anak.
Di sinilah
export
kata kunci berperan. Ini menyalin variabel shell ke lingkungan proses shell sehingga memungkinkan proses anak untuk mewarisi.Variabel lokal
Variabel lokal adalah variabel shell yang dicakup ke blok kode yang berisi mereka. Anda mendeklarasikan variabel lokal dengan
typeset
kata kunci (portabel) ataulocal
ataudeclare
(Bash). Seperti variabel shell lainnya, variabel lokal tidak diwariskan oleh proses anak. Juga variabel lokal tidak dapat diekspor.sumber