Saya tahu bahwa Bash dan Zsh mendukung local
variabel, tetapi ada sistem yang hanya memiliki shell yang kompatibel dengan POSIX. Dan local
tidak terdefinisi dalam shell POSIX.
Jadi saya ingin bertanya shell mana yang mendukung local
kata kunci untuk mendefinisikan variabel lokal?
Edit :Tentang shell yang saya maksud adalah /bin/sh
default default cangkang.
Jawaban yang Diterima:
Tidak sesederhana mendukung local
atau tidak. Ada banyak variasi pada sintaks dan cara melakukannya antara shell yang memiliki satu bentuk atau lingkup lokal lainnya.
Itulah mengapa sangat sulit untuk menghasilkan standar yang cocok untuk semua orang. Lihat http://austingroupbugs.net/bug_view_page.php?bug_id=767 untuk upaya POSIX di bagian depan itu.
cakupan lokal ditambahkan pertama kali di ksh pada awal 80-an.
Sintaks untuk mendeklarasikan variabel lokal dalam suatu fungsi adalah dengan typeset
:
function f {
typeset var=value
set -o noglob # also local to the function
...
}
(dukungan fungsi ditambahkan ke shell Bourne nanti, tetapi dengan sintaks yang berbeda (f() command
) dan ksh
menambahkan dukungan untuk yang itu juga nanti; shell Bourne tidak pernah memiliki cakupan lokal (kecuali tentu saja melalui subkulit))
local
builtin AFAIK ditambahkan pertama kali ke shell Almquist (digunakan di BSDs, dash, busybox sh) pada tahun 1989, tetapi bekerja secara signifikan berbeda dari ksh
typeset
. ash
turunan tidak mendukung typeset
sebagai alias untuk local
, tetapi Anda selalu dapat menentukannya dengan tangan.
bash dan zsh menambahkan typeset
alias ke local
masing-masing pada tahun 1989 dan 1991.
ksh88 menambahkan local
sebagai alias tidak berdokumen untuk typeset
sekitar tahun 1990 dan pdksh dan turunannya pada tahun 1994. posh
(berdasarkan pdksh
) menghapus typeset
(untuk kepatuhan yang ketat terhadap Kebijakan Debian yang memerlukan local
, tapi bukan typeset
).
POSIX awalnya keberatan untuk menentukan typeset
dengan alasan bahwa itu dinamis pelingkupan. Jadi ksh93 (penulisan ulang ksh pada tahun 1993 oleh David Korn) beralih ke statis pelingkupan sebagai gantinya. Juga di ksh93, sebagai lawan dari ksh88, pelingkupan lokal hanya dilakukan untuk fungsi yang dideklarasikan dengan ksh
sintaks (function f {...}
), bukan sintaks Bourne (f() {...}
) dan local
alias telah dihapus.
Namun ksh93v- beta dan versi final dari AT&T dapat dikompilasi dengan mode "bash" eksperimental (sebenarnya diaktifkan secara default) yang melakukan pelingkupan dinamis (dalam bentuk fungsi yang mengganggu, termasuk dengan local
dan typeset
) ketika ksh93
dipanggil sebagai bash
. local
berbeda dari typeset
dalam hal itu hanya dapat dipanggil dari dalam suatu fungsi. bash
. itu mode akan dinonaktifkan secara default di ksh2020 meskipun local
/declare
alias untuk typeset
akan dipertahankan bahkan ketika mode bash tidak dikompilasi (meskipun masih dengan pelingkupan statis).
yash
(ditulis jauh kemudian), memiliki typeset
(à la ksh88), tetapi hanya memiliki local
sebagai alias sejak versi 2.48 (Desember 2018).
@Schily mempertahankan turunan Bourne shell yang baru-baru ini dibuat sebagian besar sesuai dengan POSIX, yang disebut bosh
yang mendukung cakupan lokal sejak versi 07-07-06 (dengan local
, mirip dengan ash
).
Jadi shell seperti Bourne yang memiliki beberapa bentuk lingkup lokal untuk variabel saat ini adalah:
- ksh, semua implementasi dan turunannya (ksh88, ksh93, pdksh dan turunannya seperti posh, mksh, OpenBSD sh).
- ash dan semua turunannya (NetBSD sh, FreeBSD sh, dash, busybox sh)
- bash
- zsh
- yash
- boss
Sejauh sh
dari sistem yang berbeda pergi, perhatikan bahwa ada sistem di mana POSIX sh
ada di /bin
(sebagian besar), dan yang lainnya tidak (seperti Solaris yang ada di /usr/xpg4/bin
). Untuk sh
implementasi pada berbagai sistem yang kami miliki:
- ksh88:sebagian besar Unices komersial yang diturunkan dari SysV (AIX, HP/UX, Solaris¹…)
- bash:sebagian besar sistem GNU/Linux, Cygwin, macOS
- ash:secara default pada Debian dan sebagian besar turunannya (termasuk Ubuntu, Linux/Mint) meskipun dapat diubah oleh admin menjadi bash atau mksh. NetBSD, FreeBSD dan beberapa turunannya (bukan macOS).
- busybox sh:banyak jika bukan sebagian besar sistem Linux yang disematkan
- pdksh atau turunannya:OpenBSD, MirOS
Sekarang, di mana mereka berbeda:
typeset
(ksh, pdksh, bash, zsh, yash) vslocal
(ksh88, pdksh, bash, zsh, ash, yash 2.48+).- statis (ksh93, dalam
function f {...}
fungsi), vs pelingkupan dinamis (semua cangkang lainnya). Misalnya, apakahfunction f { typeset v=1; g; echo "$v"; }; function g { v=2; }; f
keluaran1
atau2
. Lihat juga caraexport
atribut memengaruhi pelingkupan diksh93
. - apakah
local
/typeset
buat saja variabel lokal (ash
,bosh
), atau membuat instance baru dari variabel (shell lainnya). Misalnya, apakahv=1; f() { local v; echo "${v:-empty}"; }; f
keluaran1
atauempty
(lihat jugalocalvar_inherit
opsi di bash 5.0 dan di atasnya). - dengan variabel yang membuat variabel baru, apakah variabel baru tersebut mewarisi atribut (seperti
export
) dan/atau ketik dan yang mana dari variabel dalam lingkup induk. Misalnya, apakahexport V=1; f() { local V=2; printenv V; }; f
mencetak1
,2
atau tidak sama sekali. - apakah variabel baru itu memiliki nilai awal (kosong, 0, daftar kosong, tergantung jenisnya,
zsh
) atau awalnya tidak disetel. - apakah
unset V
pada variabel dalam lingkup lokal membiarkan variabelunset
, atau cukup kupas satu tingkat pelingkupan (mksh
,yash
,bash
dalam beberapa keadaan). Misalnya, apakahv=1; f() { local v=2; unset v; echo "$v"; }
keluaran1
atau tidak sama sekali (lihat jugalocalvar_unset
opsi di bash 5.0 dan di atasnya) - suka untuk
export
, apakah itu kata kunci atau hanya bawaan atau keduanya dan dalam kondisi apa kata kunci itu dianggap sebagai kata kunci. - suka untuk
export
, apakah argumen diuraikan sebagai argumen perintah normal atau sebagai tugas (dan dalam kondisi apa). - apakah Anda dapat mendeklarasikan lokal variabel yang hanya dapat dibaca dalam cakupan induk.
- interaksi dengan
v=value myfunction
di manamyfunction
sendiri mendeklarasikanv
sebagai lokal atau tidak.
Itulah yang saya pikirkan sekarang. Periksa bug grup austin di atas untuk detail lebih lanjut.
Sejauh pelingkupan lokal untuk opsi shell (sebagai lawan dari variabel ), shell yang mendukungnya adalah:
ksh88
(dengan kedua sintaks definisi fungsi):dilakukan secara default, saya tidak mengetahui cara apa pun untuk menonaktifkannya.ash
(sejak 1989):denganlocal -
. Itu membuat$-
parameter (yang menyimpan daftar opsi) lokal.ksh93
:sekarang hanya dilakukan untukfunction f {...}
fungsi.zsh
(sejak 1995). Dengansetopt localoptions
. Juga denganemulate -L
agar mode emulasi (dan rangkaian opsinya) dibuat lokal untuk fungsi tersebut.bash
(sejak 2016) denganlocal -
seperti diash
.
Terkait:Perintah biner dan mode teks Md5sum?