Saya sebenarnya tidak tahu ada dua jenis variabel yang dapat saya akses dari baris perintah. Yang saya tahu adalah, bahwa saya dapat mendeklarasikan variabel seperti:
foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"
atau mengaksesnya dengan tanda $, seperti:
echo $foo
echo ${bar[1]}
atau menggunakan variabel bawaan, seperti:
echo $PWD
PATH=$PATH:"/usr/bin/myProg"
Sekarang, saya dengar ada dua (setidaknya?) Jenis variabel: variabel shell dan variabel lingkungan.
- Apa tujuan dari memiliki dua tipe yang berbeda?
- Bagaimana saya tahu tipe variabel apa?
- Apa penggunaan khas untuk masing-masing?
shell
command-line
environment-variables
sharkant
sumber
sumber
Jawaban:
Variabel lingkungan adalah daftar
name=value
pasangan yang ada apa pun programnya (shell, aplikasi, daemon ...). Mereka biasanya diwarisi oleh proses anak-anak (dibuat olehfork
/exec
urutan): proses anak-anak mendapatkan salinan variabel orangtua mereka sendiri.Variabel shell memang hanya ada dalam konteks shell. Mereka hanya diwariskan dalam subkulit (yaitu ketika shell bercabang tanpa
exec
operasi). Tergantung pada fitur shell, variabel mungkin tidak hanya string sederhana seperti yang lingkungan tetapi juga array, senyawa, variabel yang diketik seperti integer atau floating point, dll.Ketika shell dimulai, semua variabel lingkungan yang diwarisi dari induknya juga menjadi variabel shell (kecuali jika variabel tersebut tidak valid sebagai variabel shell dan kasus sudut lainnya seperti
IFS
yang disetel ulang oleh beberapa shell) tetapi variabel yang diwarisi ini ditandai sebagai diekspor 1 . Itu berarti mereka akan tetap tersedia untuk proses anak-anak dengan nilai yang berpotensi diperbarui yang ditetapkan oleh shell. Itu juga kasus dengan variabel yang dibuat di bawah shell dan ditandai sebagai diekspor denganexport
kata kunci.Array dan variabel tipe kompleks lainnya tidak dapat diekspor kecuali nama dan nilainya dapat dikonversi ke
name=value
pola, atau ketika mekanisme spesifik shell ada (misalnya:bash
fungsi ekspor di lingkungan dan beberapa shell eksotis, non POSIX sepertirc
danes
dapat mengekspor array ).Jadi perbedaan utama antara variabel lingkungan dan variabel shell adalah cakupannya: variabel lingkungan bersifat global sedangkan variabel shell yang tidak diekspor adalah lokal untuk skrip.
Perhatikan juga bahwa shell modern (setidaknya
ksh
danbash
) mendukung cakupan variabel shell ketiga. Variabel yang dibuat dalam fungsi dengantypeset
kata kunci bersifat lokal untuk fungsi tersebut (Cara fungsi ini dideklarasikan mengaktifkan / menonaktifkan fitur iniksh
, dan perilaku persistensi berbeda antarabash
danksh
). Lihat /unix//a/28349/25941 ini berlaku untuk kerang yang modern seperti
ksh
,dash
,bash
dan yang sejenis. Cangkang Bourne warisan dan cangkang sintaksis bukan Bournecsh
memiliki perilaku yang berbeda.sumber
execve()
panggilan sistem demikian juga (biasanya) digunakan untuk bertahan data selama eksekusi perintah lain (dalam proses yang sama).IFS
pada beberapa shell).rc
,es
dapat mengekspor array menggunakan pengkodean adhoc.bash
danrc
juga dapat mengekspor fungsi menggunakan variabel lingkungan (sekali lagi, menggunakan pengkodean khusus).ksh93
,typeset
membatasi ruang lingkup hanya dalam fungsi yang dideklarasikan denganfunction foo { ...; }
sintaks, bukan denganfoo() cmd
sintaks Bourne ( ) (dan itu pelingkupan statis tidak dinamis seperti di shell lain).Variabel shell
Variabel Shell adalah variabel yang ruang lingkupnya dalam sesi shell saat ini, misalnya dalam sesi shell interaktif atau skrip.
Anda dapat membuat variabel shell dengan menetapkan nilai ke nama yang tidak digunakan:
Penggunaan variabel shell adalah untuk melacak data di sesi saat ini. Variabel Shell biasanya memiliki nama dengan huruf kecil.
Variabel lingkungan
Variabel lingkungan adalah variabel shell yang telah diekspor. Ini berarti bahwa itu akan terlihat sebagai variabel, tidak hanya di sesi shell yang membuatnya, tetapi juga untuk setiap proses (bukan hanya shell) yang dimulai dari sesi itu.
atau
Setelah variabel shell telah diekspor, ia tetap diekspor sampai tidak disetel, atau sampai "properti ekspor" dihapus (dengan
export -n
inbash
), jadi biasanya tidak perlu untuk mengekspornya kembali. Membatalkan pengaturan variabel denganunset
menghapusnya (tidak peduli apakah itu variabel lingkungan atau tidak).Array dan hash asosiatif dalam
bash
dan shell lain mungkin tidak diekspor untuk menjadi variabel lingkungan. Variabel lingkungan harus berupa variabel sederhana yang nilainya berupa string, dan mereka sering memiliki nama yang terdiri dari huruf besar.Penggunaan variabel lingkungan adalah untuk melacak data dalam sesi shell saat ini, tetapi juga untuk memungkinkan setiap proses yang dimulai untuk mengambil bagian dari data itu. Kasus khas ini adalah
PATH
variabel lingkungan, yang dapat diatur dalam shell dan kemudian digunakan oleh program apa pun yang ingin memulai program tanpa menentukan path lengkap ke mereka.Pengumpulan variabel lingkungan dalam suatu proses sering disebut sebagai "lingkungan proses". Setiap proses memiliki lingkungannya sendiri.
Variabel lingkungan hanya dapat "diteruskan", yaitu proses anak tidak pernah dapat mengubah variabel lingkungan dalam proses induknya, dan selain menyiapkan lingkungan untuk proses anak setelah memulainya, proses induk mungkin tidak mengubah lingkungan yang ada dari suatu proses anak.
Variabel lingkungan dapat didaftar dengan
env
(tanpa argumen). Selain itu, mereka muncul sama dengan variabel shell yang tidak diekspor dalam sesi shell. Ini sedikit istimewa untuk shell karena kebanyakan bahasa pemrograman lain biasanya tidak mencampurkan variabel "biasa" dengan variabel lingkungan (lihat di bawah).env
dapat juga digunakan untuk mengatur nilai satu atau beberapa variabel lingkungan di lingkungan suatu proses tanpa mengaturnya di sesi saat ini:Ini dimulai
make
dengan variabel lingkunganCC
diatur ke nilaiclang
danCXX
diatur keclang++
.Ini juga dapat digunakan untuk membersihkan lingkungan untuk suatu proses:
Ini dimulai
bash
tetapi tidak mentransfer lingkungan saat ini kebash
proses baru (masih akan memiliki variabel lingkungan karena menciptakan yang baru dari skrip inisialisasi shell-nya).Contoh perbedaan
Bahasa lainnya
Ada fungsi perpustakaan di sebagian besar bahasa pemrograman yang memungkinkan untuk mendapatkan dan mengatur variabel lingkungan. Perhatikan bahwa karena variabel lingkungan disimpan sebagai hubungan nilai kunci yang sederhana, mereka biasanya bukan "variabel" bahasa. Suatu program dapat mengambil nilai (yang selalu berupa string karakter) yang terkait dengan kunci (nama variabel lingkungan), tetapi kemudian harus mengonversinya menjadi bilangan bulat atau apa pun tipe data apa pun yang diharapkan memiliki nilai oleh bahasa.
Dalam C, variabel lingkungan dapat diakses menggunakan
getenv()
,setenv()
,putenv()
danunsetenv()
. Variabel yang dibuat dengan rutinitas ini diwarisi dengan cara yang sama dengan proses apa pun yang dimulai program C.Bahasa lain mungkin memiliki struktur data khusus untuk mencapai hal yang sama, seperti
%ENV
hash di Perl, atauENVIRON
array asosiatif di sebagian besar implementasiawk
.sumber
getenv()
,setenv()
,putenv()
danunsetenv()
. Variabel yang dibuat dengan rutinitas ini diwarisi dengan cara yang sama dengan proses apa pun yang dimulai program C. Bahasa lain mungkin memiliki struktur data khusus untuk hal yang sama, seperti%ENV
di Perl.exec*()
keluarga fungsi juga dapat mengatur lingkungan untuk proses yang dieksekusi.Variabel Shell sulit untuk diduplikasi.
Namun variabel lingkungan dapat diduplikasi; mereka hanya daftar, dan daftar dapat memiliki entri duplikat. Ini
envdup.c
untuk melakukan hal itu.Yang dapat kita kompilasi dan jalankan jitu
envdup
untuk kemudian dijalankanenv
untuk menunjukkan kepada kita variabel lingkungan apa yang ditetapkan ...Ini mungkin hanya berguna untuk menemukan bug atau keanehan lain dalam seberapa baik program menangani
**environ
.Sepertinya Python 3.6 di sini secara membabi buta melewati duplikat (abstraksi yang bocor) sementara Perl 5.24 tidak. Bagaimana dengan kerang?
Astaga, apa yang terjadi jika
sudo
hanya membersihkan entri lingkungan pertama tetapi kemudianbash
berjalan dengan yang kedua? HaloPATH
atauLD_RUN_PATH
exploit. Apakah Andasudo
(dan yang lainnya ?) Ditambal untuk lubang itu ? Eksploitasi keamanan bukanlah "perbedaan anekdotal" atau hanya "bug" dalam program panggilan.sumber
Sebuah variabel lingkungan seperti variabel shell , tapi tidak spesifik untuk shell . Semua proses pada sistem Unix memiliki penyimpanan variabel lingkungan . Perbedaan utama antara variabel lingkungan dan shell adalah: bahwa sistem operasi meneruskan semua variabel lingkungan shell Anda ke program yang dijalankan shell, sedangkan variabel shell tidak dapat diakses dalam perintah yang Anda jalankan.
env –
Perintah ini memungkinkan Anda untuk menjalankan program lain di lingkungan kustom tanpa mengubah yang saat ini. Ketika digunakan tanpa argumen, ia akan mencetak daftar variabel lingkungan saat ini.printenv –
Perintah mencetak semua atau variabel lingkungan yang ditentukan.set –
Perintah mengatur atau membatalkan variabel shell. Ketika digunakan tanpa argumen, ia akan mencetak daftar semua variabel termasuk variabel lingkungan dan shell, dan fungsi shell.unset –
Perintah menghapus variabel shell dan lingkungan.export –
Perintah ini mengatur variabel lingkungansumber