Je sais que Bash et Zsh supportent local
variables, mais certains systèmes n'ont que des shells compatibles POSIX. Et local
n'est pas défini dans les shells POSIX.
Je veux donc demander quels shells prennent en charge local
mot clé pour définir les variables locales ?
Modifier :À propos des shells, je veux dire la valeur par défaut /bin/sh
coquille.
Réponse acceptée :
Ce n'est pas aussi simple que de prendre en charge local
ou pas. Il existe de nombreuses variations dans la syntaxe et la façon dont cela se fait entre les shells qui ont une forme ou une autre de portée locale.
C'est pourquoi il est très difficile de trouver une norme qui convienne à tous. Voir http://austingroupbugs.net/bug_view_page.php?bug_id=767 pour l'effort POSIX sur ce front.
la portée locale a été ajoutée pour la première fois dans ksh au début des années 80.
La syntaxe pour déclarer une variable locale dans une fonction était avec typeset
:
function f {
typeset var=value
set -o noglob # also local to the function
...
}
(la prise en charge de la fonction a été ajoutée au shell Bourne plus tard, mais avec une syntaxe différente (commande f() command
) et ksh
ajout d'un support pour celui-là également plus tard ; le shell Bourne n'a jamais eu de portée locale (sauf bien sûr via les sous-shells))
Le local
builtin AFAIK a été ajouté pour la première fois au shell Almquist (utilisé dans les BSD, dash, busybox sh) en 1989, mais fonctionne de manière très différente de ksh
est typeset
. ash
les dérivés ne prennent pas en charge typeset
comme alias de local
, mais vous pouvez toujours en définir un à la main.
bash et zsh ont ajouté typeset
alias local
en 1989 et 1991 respectivement.
ksh88 a ajouté local
en tant qu'alias non documenté de typeset
vers 1990 et pdksh et ses dérivés en 1994. posh
(basé sur pdksh
) supprimé typeset
(pour une stricte conformité à la politique Debian qui requiert local
, mais pas typeset
).
POSIX s'est initialement opposé à la spécification de typeset
au motif qu'il était dynamique portée. Donc ksh93 (une réécriture de ksh en 1993 par David Korn) est passé à statique portée à la place. Aussi dans ksh93, contrairement à ksh88, la portée locale n'est effectuée que pour les fonctions déclarées avec le ksh
syntaxe (function f {...}
), pas la syntaxe Bourne (f() {...}
) et le local
alias a été supprimé.
Cependant, la version ksh93v-beta et finale d'AT&T peut être compilée avec un mode "bash" expérimental (en fait activé par défaut) qui effectue une portée dynamique (dans les deux formes de fonctions, y compris avec local
et typeset
) lorsque ksh93
est invoqué en tant que bash
. local
diffère de typeset
dans ce cas, en ce sens qu'il ne peut être appelé qu'à partir d'une fonction. Ce bash
le mode sera désactivé par défaut dans ksh2020 si le local
/declare
alias vers typeset
sera conservé même lorsque le mode bash n'est pas compilé (mais toujours avec une portée statique).
yash
(écrit beaucoup plus tard), a typeset
(à la ksh88), mais n'a eu que local
comme alias depuis la version 2.48 (décembre 2018).
@Schily maintient un descendant du shell Bourne qui a récemment été rendu principalement conforme à POSIX, appelé bosh
qui prend en charge la portée locale depuis la version 2016-07-06 (avec local
, similaire à ash
).
Ainsi, les shells de type Bourne qui ont une certaine forme de portée locale pour les variables aujourd'hui sont :
- ksh, toutes les implémentations et leurs dérivés (ksh88, ksh93, pdksh et dérivés comme posh, mksh, OpenBSD sh).
- ash et tous ses dérivés (NetBSD sh, FreeBSD sh, dash, busybox sh)
- bash
- zsh
- yash
- bosh
En ce qui concerne le sh
de différents systèmes vont, notez qu'il existe des systèmes où le POSIX sh
est dans /bin
(la plupart), et d'autres où ce n'est pas (comme Solaris où c'est dans /usr/xpg4/bin
). Pour le sh
mise en œuvre sur divers systèmes que nous avons :
- ksh88 :la plupart des Unix commerciaux dérivés de SysV (AIX, HP/UX, Solaris¹…)
- bash :la plupart des systèmes GNU/Linux, Cygwin, macOS
- ash :par défaut sur Debian et la plupart des dérivés (y compris Ubuntu, Linux/Mint) mais peut être modifié par l'administrateur en bash ou mksh. NetBSD, FreeBSD et certains de leurs dérivés (pas macOS).
- busybox sh :de nombreux systèmes Linux embarqués, sinon la plupart
- pdksh ou dérivés :OpenBSD, MirOS
Maintenant, où ils diffèrent :
typeset
(ksh, pdksh, bash, zsh, yash) vslocal
(ksh88, pdksh, bash, zsh, cendre, yash 2.48+).- statique (ksh93, dans
function f {...}
fonction), vs portée dynamique (tous les autres shells). Par exemple, sifunction f { typeset v=1; g; echo "$v"; }; function g { v=2; }; f
sorties1
ou2
. Voir aussi comment l'export
l'attribut affecte la portée dansksh93
. - si
local
/typeset
rend juste la variable locale (ash
,bosh
), ou crée une nouvelle instance de la variable (autres shells). Par exemple, siv=1; f() { local v; echo "${v:-empty}"; }; f
sorties1
ouempty
(voir aussi lelocalvar_inherit
option dans bash 5.0 et supérieur). - avec ceux qui créent une nouvelle variable, si la nouvelle hérite des attributs (comme
export
) et/ou type et lesquels de la variable dans la portée parent. Par exemple, siexport V=1; f() { local V=2; printenv V; }; f
imprime1
,2
ou rien. - si cette nouvelle variable a une valeur initiale (vide, 0, liste vide, selon le type,
zsh
) ou est initialement non défini. - si
unset V
sur une variable dans une portée locale laisse la variableunset
, ou simplement peler un niveau de portée (mksh
,yash
,bash
dans certaines circonstances). Par exemple, siv=1; f() { local v=2; unset v; echo "$v"; }
sorties1
ou rien (voir aussi lelocalvar_unset
option dans bash 5.0 et supérieur) - comme pour
export
, s'il s'agit d'un mot-clé ou seulement d'un simple élément intégré ou les deux et dans quelles conditions il est considéré comme un mot-clé. - comme pour
export
, si les arguments sont analysés comme des arguments de commande normaux ou comme des affectations (et dans quelles conditions). - si vous pouvez déclarer local une variable qui était en lecture seule dans la portée parent.
- les interactions avec
v=value myfunction
oùmyfunction
déclare lui-mêmev
comme local ou non.
C'est à eux que je pense tout à l'heure. Vérifiez le bogue du groupe Austin ci-dessus pour plus de détails.
En ce qui concerne la portée locale des options du shell (par opposition aux variables ), les shells qui le supportent sont :
ksh88
(avec les deux syntaxes de définition de fonction) :fait par défaut, je ne connais aucun moyen de le désactiver.ash
(depuis 1989) :aveclocal -
. Cela fait le$-
paramètre (qui stocke la liste des options) local.ksh93
:maintenant seulement fait pourfunction f {...}
fonctions.zsh
(depuis 1995). Avecsetopt localoptions
. Aussi avecemulate -L
pour que le mode d'émulation (et son ensemble d'options) soit rendu local à la fonction.bash
(depuis 2016) aveclocal -
comme dansash
.
En relation:Mode binaire et texte de la commande Md5sum?