GNU/Linux >> Tutoriels Linux >  >> Linux

Liste des shells prenant en charge le mot-clé "local" pour définir des variables locales ?

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 relation :comparer deux colonnes de fichiers différents et imprimer si cela correspond ?

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) vs local (ksh88, pdksh, bash, zsh, cendre, yash 2.48+).
  • statique (ksh93, dans function f {...} fonction), vs portée dynamique (tous les autres shells). Par exemple, si function f { typeset v=1; g; echo "$v"; }; function g { v=2; }; f sorties 1 ou 2 . Voir aussi comment l'export l'attribut affecte la portée dans ksh93 .
  • si local /typeset rend juste la variable locale (ash , bosh ), ou crée une nouvelle instance de la variable (autres shells). Par exemple, si v=1; f() { local v; echo "${v:-empty}"; }; f sorties 1 ou empty (voir aussi le localvar_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, si export V=1; f() { local V=2; printenv V; }; f imprime 1 , 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 variable unset , ou simplement peler un niveau de portée (mksh , yash , bash dans certaines circonstances). Par exemple, si v=1; f() { local v=2; unset v; echo "$v"; } sorties 1 ou rien (voir aussi le localvar_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 myfunctionmyfunction déclare lui-même v 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) :avec local - . Cela fait le $- paramètre (qui stocke la liste des options) local.
  • ksh93 :maintenant seulement fait pour function f {...} fonctions.
  • zsh (depuis 1995). Avec setopt localoptions . Aussi avec emulate -L pour que le mode d'émulation (et son ensemble d'options) soit rendu local à la fonction.
  • bash (depuis 2016) avec local - comme dans ash .

En relation:Mode binaire et texte de la commande Md5sum?
Linux
  1. Comment configurer virt-manager pour la prise en charge de la virtualisation imbriquée ?

  2. Espaces pour les variables dans le script bash ?

  3. Linux - Prise en charge générale de Linux pour Ipv6 Prêt ?

  4. Une liste impressionnante d'applications et de ressources pour le système d'exploitation élémentaire

  5. Bash for loop Exemples

Comment définir et répertorier les variables d'environnement sous Linux

Comment définir et répertorier les variables d'environnement sous Linux

Top 6 des shells open source pour Linux

Une liste de services de console utiles pour les utilisateurs de Linux

Bash Scripting - Boucle For expliquée avec des exemples

Top 10 des meilleurs antivirus pour Linux – Liste des logiciels antivirus Linux !