So che Bash e Zsh supportano local
variabili, ma ci sono sistemi che hanno solo shell compatibili con POSIX. E local
non è definito nelle shell POSIX.
Quindi voglio chiedere quali shell supportano local
parola chiave per definire le variabili locali?
Modifica :Per quanto riguarda le shell intendo il predefinito /bin/sh
conchiglia.
Risposta accettata:
Non è semplice come supportare local
o no. Ci sono molte variazioni sulla sintassi e su come viene eseguita tra shell che hanno una forma o l'altra di ambito locale.
Ecco perché è molto difficile trovare uno standard che sia d'accordo con tutti. Vedi http://austingroupbugs.net/bug_view_page.php?bug_id=767 per lo sforzo POSIX su questo fronte.
l'ambito locale è stato aggiunto per la prima volta in ksh all'inizio degli anni '80.
La sintassi per dichiarare una variabile locale in una funzione era con typeset
:
function f {
typeset var=value
set -o noglob # also local to the function
...
}
(il supporto per le funzioni è stato aggiunto alla shell Bourne in seguito, ma con una sintassi diversa (comando f() command
) e ksh
aggiunto il supporto anche per quello in seguito; la shell Bourne non ha mai avuto un ambito locale (tranne ovviamente tramite subshell))
Il local
il builtin AFAIK è stato aggiunto per la prima volta alla shell Almquist (usata in BSD, dash, busybox sh) nel 1989, ma funziona in modo significativamente diverso da ksh
's typeset
. ash
i derivati non supportano typeset
come alias per local
, ma puoi sempre definirne uno a mano.
bash e zsh hanno aggiunto typeset
alias local
rispettivamente nel 1989 e nel 1991.
ksh88 ha aggiunto local
come alias non documentato per typeset
intorno al 1990 e pdksh e suoi derivati nel 1994. posh
(basato su pdksh
) rimosso typeset
(per la stretta conformità alla politica Debian che richiede local
, ma non typeset
).
POSIX inizialmente si è opposto alla specifica di typeset
sulla base del fatto che era dinamico scoping. Quindi ksh93 (una riscrittura di ksh nel 1993 da David Korn) è passato a statico invece lo scopo. Anche in ksh93, al contrario di ksh88, l'ambito locale viene eseguito solo per le funzioni dichiarate con ksh
sintassi (function f {...}
), non la sintassi Bourne (f() {...}
) e il local
l'alias è stato rimosso.
Tuttavia, ksh93v-beta e la versione finale di AT&T possono essere compilate con una modalità sperimentale "bash" (effettivamente abilitata per impostazione predefinita) che esegue l'ambito dinamico (in entrambe le forme di funzioni, incluso con local
e typeset
) quando ksh93
viene invocato come bash
. local
differisce da typeset
in tal caso in quanto può essere invocato solo dall'interno di una funzione. Quella bash
la modalità sarà disabilitata per impostazione predefinita in ksh2020 tramite local
/declare
alias per typeset
verrà mantenuto anche quando la modalità bash non è compilata (sebbene ancora con l'ambito statico).
yash
(scritto molto più tardi), ha typeset
(à la ksh88), ma ha avuto solo local
come alias dalla versione 2.48 (dicembre 2018).
@Schily mantiene un discendente della shell Bourne che è stato recentemente reso per lo più conforme a POSIX, chiamato bosh
che supporta l'ambito locale dalla versione 2016-07-06 (con local
, simile a ash
).
Quindi le shell simili a Bourne che hanno una qualche forma di ambito locale per le variabili oggi sono:
- ksh, tutte le implementazioni e i loro derivati (ksh88, ksh93, pdksh e derivati come posh, mksh, OpenBSD sh).
- ash e tutti i suoi derivati (NetBSD sh, FreeBSD sh, dash, busybox sh)
- bash
- zsh
- sì
- Bosh
Per quanto riguarda il sh
di sistemi diversi, nota che ci sono sistemi in cui POSIX sh
è in /bin
(la maggior parte) e altri dove non lo è (come Solaris dove si trova in /usr/xpg4/bin
). Per il sh
implementazione su vari sistemi abbiamo:
- ksh88:la maggior parte degli Unice commerciali derivati da SysV (AIX, HP/UX, Solaris¹...)
- bash:la maggior parte dei sistemi GNU/Linux, Cygwin, macOS
- ash:per impostazione predefinita su Debian e la maggior parte dei derivati (incluso Ubuntu, Linux/Mint) anche se può essere modificato dall'amministratore in bash o mksh. NetBSD, FreeBSD e alcuni dei loro derivati (non macOS).
- busybox sh:molti se non la maggior parte dei sistemi Linux embedded
- pdksh o derivati:OpenBSD, MirOS
Ora, dove differiscono:
typeset
(ksh, pdksh, bash, zsh, yash) vslocal
(ksh88, pdksh, bash, zsh, ash, yash 2.48+).- statico (ksh93, in
function f {...}
funzione), rispetto all'ambito dinamico (tutte le altre shell). Ad esempio, sefunction f { typeset v=1; g; echo "$v"; }; function g { v=2; }; f
emette1
o2
. Guarda anche comeexport
l'attributo influisce sull'ambito inksh93
. - se
local
/typeset
rende semplicemente la variabile locale (ash
,bosh
) o crea una nuova istanza della variabile (altre shell). Ad esempio, sev=1; f() { local v; echo "${v:-empty}"; }; f
emette1
oempty
(vedi anche illocalvar_inherit
opzione in bash 5.0 e versioni successive). - con quelli che creano una nuova variabile, se la nuova eredita gli attributi (come
export
) e/o tipo e quali dalla variabile nell'ambito padre. Ad esempio, seexport V=1; f() { local V=2; printenv V; }; f
stampa1
,2
o niente. - se la nuova variabile ha un valore iniziale (vuoto, 0, elenco vuoto, a seconda del tipo,
zsh
) o inizialmente non è impostato. - se
unset V
su una variabile in un ambito locale lascia la variabileunset
o semplicemente peeling un livello di ambito (mksh
,yash
,bash
in alcune circostanze). Ad esempio, sev=1; f() { local v=2; unset v; echo "$v"; }
emette1
o niente (vedi anche illocalvar_unset
opzione in bash 5.0 e versioni successive) - mi piace per
export
, indipendentemente dal fatto che si tratti di una parola chiave o solo di un semplice built-in o di entrambi e in quali condizioni è considerata una parola chiave. - mi piace per
export
, se gli argomenti vengono analizzati come normali argomenti di comando o come assegnazioni (e in quali condizioni). - se puoi dichiarare locale una variabile che era di sola lettura nell'ambito padre.
- le interazioni con
v=value myfunction
dovemyfunction
stesso dichiarav
come locale o meno.
Sono quelli a cui sto pensando proprio ora. Controlla il bug del gruppo austin sopra per maggiori dettagli.
Per quanto riguarda l'ambito locale per le opzioni della shell (al contrario di variabili ), le shell che lo supportano sono:
ksh88
(con entrambe le sintassi di definizione delle funzioni):fatto per impostazione predefinita, non sono a conoscenza di alcun modo per disabilitarlo.ash
(dal 1989):conlocal -
. Rende il$-
parametro (che memorizza l'elenco delle opzioni) local.ksh93
:ora fatto solo perfunction f {...}
funzioni.zsh
(dal 1995). Consetopt localoptions
. Anche conemulate -L
affinché la modalità di emulazione (e il relativo insieme di opzioni) sia resa locale alla funzione.bash
(dal 2016) conlocal -
come inash
.
Correlati:comando Md5sum binario e modalità testo?