Variabel Lingkungan vs Parameter Posisi
Sebelum kita mulai membahas $INTEGERjenis variabel, kita perlu memahami apa sebenarnya mereka dan bagaimana mereka berbeda dari variabel lingkungan. Variabel seperti $INTEGERdisebut parameter posisi. Ini dijelaskan dalam standar POSIX (Portable Operating System Interface), bagian 2.1 (penekanan tambang):
- Shell mengeksekusi fungsi (lihat Perintah Definisi Fungsi), built-in (lihat Utilitas Built-In Khusus), file yang dapat dieksekusi, atau skrip, memberikan nama argumen sebagai parameter posisi bernomor 1 hingga n, dan nama perintah (atau dalam kasus fungsi dalam skrip, nama skrip) sebagai parameter posisional bernomor 0 (lihat Pencarian Perintah dan Eksekusi).
Sebaliknya, variabel seperti $HOMEdan $PATHadalah variabel lingkungan. Definisi mereka dijelaskan di bagian 8 dari standar :
Variabel lingkungan yang didefinisikan dalam bab ini memengaruhi operasi beberapa utilitas, fungsi, dan aplikasi. Ada variabel lingkungan lain yang hanya menarik untuk utilitas tertentu. Variabel lingkungan yang berlaku untuk satu utilitas saja didefinisikan sebagai bagian dari deskripsi utilitas.
Perhatikan deskripsi mereka. Parameter posisi dimaksudkan untuk muncul di depan perintah, yaitu command positional_arg_1 positional_arg_2.... Mereka dimaksudkan untuk disediakan oleh pengguna untuk memberi tahu perintah apa yang harus dilakukan secara spesifik. Ketika Anda melakukannya echo 'Hello' 'World', itu akan mencetak Hellodan Worldstring, karena ini adalah parameter posisi untuk echo- hal-hal yang ingin Anda echooperasikan. Dan echodibangun sedemikian sehingga memahami parameter posisi sebagai string yang akan dicetak (kecuali jika mereka salah satu dari bendera opsional seperti -n). Jika Anda melakukan ini dengan perintah yang berbeda mungkin tidak mengerti apa HellodanWorldkarena mungkin mengharapkan nomor. Perhatikan bahwa parameter posisi tidak "diwariskan" - proses anak tidak tahu tentang parameter posisi orang tua kecuali secara eksplisit diteruskan ke proses anak. Seringkali Anda melihat parameter posisi diteruskan dengan skrip pembungkus - yang mungkin memeriksa contoh perintah yang sudah ada atau menambahkan parameter posisi tambahan ke perintah nyata yang akan dipanggil.
Sebaliknya, variabel lingkungan dimaksudkan untuk mempengaruhi banyak program. Mereka adalah variabel lingkungan , karena mereka ditetapkan di luar program itu sendiri (lebih lanjut tentang ini di bawah). Variabel lingkungan tertentu seperti HOMEatau PATHmemiliki format spesifik, makna spesifik, dan mereka akan berarti sama untuk setiap program. HOMEvariabel akan berarti sama dengan utilitas eksternal seperti /usr/bin/findatau shell Anda (dan akibatnya untuk skrip) - itu adalah direktori home dari nama pengguna di mana proses berjalan. Perhatikan bahwa variabel lingkungan dapat digunakan untuk menjelaskan perilaku perintah tertentu, misalnyaUIDvariabel lingkungan dapat digunakan untuk memeriksa apakah skrip berjalan dengan hak akses root atau tidak dan cabang ke tindakan tertentu yang sesuai. Variabel lingkungan dapat diwariskan - proses anak mendapatkan salinan dari lingkungan orang tua. Lihat juga Jika proses mewarisi lingkungan induk, mengapa kita perlu ekspor?
Singkatnya, perbedaan utama adalah bahwa variabel lingkungan ditetapkan di luar perintah dan tidak dimaksudkan untuk bervariasi (biasanya), sedangkan parameter posisi adalah hal-hal yang dimaksudkan untuk diproses oleh perintah dan mereka berubah.
Bukan hanya konsep shell
Yang saya perhatikan dari komentar adalah bahwa Anda mencampur terminal dan shell, dan akan sangat menyarankan Anda membaca tentang terminal nyata yang pada suatu waktu adalah perangkat fisik. Saat ini, "terminal" yang biasanya kita rujuk, jendela dengan latar belakang hitam dan teks hijau sebenarnya adalah perangkat lunak, sebuah proses. Terminal adalah program yang menjalankan shell, sementara shell juga merupakan program tetapi yang membaca apa yang Anda ketik untuk dieksekusi (yaitu, jika shell interaktif; shell non-interaktif adalah skrip dan sh -c 'echo foo'jenis doa). Lebih lanjut tentang kerang di sini .
Ini adalah perbedaan penting, tetapi juga penting untuk mengenali bahwa terminal adalah program dan karena itu mematuhi aturan lingkungan dan parameter posisi yang sama. Saat Anda gnome-terminalmulai akan melihat SHELLvariabel lingkungan Anda , dan menelurkan shell default yang sesuai untuk Anda, kecuali jika Anda menentukan beberapa perintah lain dengan -e. Katakanlah saya berubah shell default saya ke ksh - gnome-terminal kemudian akan menelurkan kshbukan bash. Itu juga contoh bagaimana lingkungan digunakan oleh program. Jika saya secara eksplisit meminta gnome-terminaldengan -emenjalankan shell tertentu - itu akan melakukannya, tetapi itu tidak akan permanen. Sebaliknya, lingkungan seharusnya sebagian besar tidak berubah (lebih lanjut tentang itu nanti).
Jadi seperti yang Anda lihat, variabel lingkungan dan posisi keduanya adalah properti dari suatu proses / perintah, bukan hanya shell. Ketika datang ke skrip shell, mereka juga mengikuti model yang ditetapkan oleh bahasa pemrograman C. Ambil contoh mainfungsi C yang biasanya terlihat
int main(int argc, char **argv)
, di mana argcada sejumlah argumen baris perintah dan argvsecara efektif array parameter baris perintah, dan kemudian ada environfungsi (di Linux itu man -e 7 environ) untuk mengakses hal-hal seperti jalur direktori home pengguna, daftar direktori di PATHmana kita dapat mencari executable, dll. Script Shell juga dimodelkan dengan cara yang sama. Dalam terminologi shell, kami memiliki parameter posisi $1, $2dan sebagainya, sedangkan $#jumlah parameter posisi. Bagaimana dengan $0? Itulah nama executable itu sendiri, yang lagi-lagi dimodelkan dari bahasa pemrograman C - argv[0]akan menjadi nama C Anda "executable". Dan ini cukup benar untuk sebagian besar bahasa pemrograman dan scripting .
Kerang Interaktif vs Non-interaktif
Salah satu hal yang telah saya isyaratkan adalah perbedaan antara cangkang interaktif dan non-interaktif . Prompt tempat Anda mengetik perintah - yang interaktif, berinteraksi dengan pengguna. Sebaliknya ketika Anda memiliki skrip shell atau Anda menjalankan bash -c''itu non-interaktif.
Dan di sinilah perbedaan menjadi penting. Shell yang Anda jalankan sudah merupakan proses, yang muncul dengan parameter posisi (untuk bashshell login adalah satu "... yang karakter pertama argumen nol adalah -, atau yang dimulai dengan opsi --login." ( Referensi ) )
Sebaliknya, skrip dan shell yang diluncurkan dengan -copsi dapat memanfaatkan $1dan $2argumen. Contohnya,
$ bash -c 'echo $1; stat $2' sh 'Hello World' /etc/passwd
Hello World
File: '/etc/passwd'
Size: 2913 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 6035604 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017-08-12 14:48:37.125879962 -0600
Modify: 2017-08-12 14:48:37.125879962 -0600
Change: 2017-08-12 14:48:37.137879811 -0600
Birth: -
Perhatikan bahwa saya juga pernah menggunakannya di shsana, karena kekhasan kecil dari -copsi adalah untuk mengambil parameter posisi pertama dan menetapkannya $0, tidak seperti biasanya menjadi nama program.
Hal lain yang penting untuk diperhatikan adalah bahwa parameter posisi adalah apa yang saya sebut "framable". Perhatikan caranya, kami pertama kali meluncurkan bashdengan parameter posisinya sendiri, tetapi parameter posisional itu menjadi parameter untuk echodan stat. Dan setiap program memahaminya dengan caranya sendiri. Jika kami berikan ke statstring Hello Worlddan tidak ada file Hello Worlditu akan menghasilkan kesalahan; bashmemperlakukannya hanya sebagai string sederhana tetapi statmengharapkan string itu menjadi nama file yang ada. Sebaliknya, semua program akan setuju bahwa variabel lingkungan HOMEadalah direktori (kecuali programmer mengkodekannya dengan cara yang tidak masuk akal).
Bisakah kita dipusingkan dengan variabel lingkungan dan parameter posisi?
Secara teknis, kita bisa dipusingkan dengan keduanya, tetapi kita tidak boleh dipusingkan dengan variabel lingkungan, sementara kita sering harus memberikan parameter posisi. Kita dapat menjalankan perintah di shell dengan menambahkan variabel, misalnya:
$ hello=world bash -c 'echo $hello'
world
Kami juga dapat menempatkan variabel ke lingkungan hanya menggunakan export variable=valuedari dalam shell atau skrip. Atau kita dapat menjalankan perintah dengan lingkungan yang benar-benar kosong env -c command arg1 arg2. Namun, biasanya tidak disarankan untuk dipusingkan dengan lingkungan, terutama menggunakan variabel huruf besar atau menimpa variabel lingkungan yang sudah ada. Perhatikan bahwa itu direkomendasikan meskipun bukan standar.
Untuk parameter posisi, cara untuk mengaturnya jelas, cukup tambahkan mereka ke perintah, tetapi juga ada cara untuk mengaturnya dengan bijaksana , serta mengubah daftar parameter tersebut melalui shiftperintah.
Kesimpulannya, tujuan keduanya berbeda, dan mereka ada karena suatu alasan. Saya harap orang-orang mendapatkan beberapa wawasan dari jawaban ini, dan itu menyenangkan membacanya sama seperti saya menulis jawaban ini.
Catatan pada perintah yang ditetapkan
The setperintah, menurut berperilaku pengguna seperti begitu (dari manual bash, penekanan ditambahkan):
Tanpa opsi, nama dan nilai setiap variabel shell ditampilkan dalam format yang dapat digunakan kembali sebagai input untuk mengatur atau mengatur ulang variabel yang saat ini ditetapkan.
Dengan kata lain, setlihat variabel spesifik untuk shell, beberapa di antaranya terjadi di lingkungan, misalnya HOME. Sebaliknya, perintah suka envdan printenvlihat variabel lingkungan aktual yang digunakan perintah. Lihat juga ini .
export 3dapat berubah$3menjadi variabel lingkungan. Kamu tidak bisaunset 3; dan Anda tidak dapat menetapkan$3nilai baru menggunakan3=val.