Existe-t-il un moyen concis de tester la prise en charge des tableaux par le shell local de type Bourne sur la ligne de commande?
C'est toujours possible:
$ arr=(0 1 2 3);if [ "${arr[2]}" != 2 ];then echo "No array support";fi
ou tester $SHELL
et version shell:
$ eval $(echo "$SHELL --version") | grep version
puis en lisant la page de manuel, en supposant que j'y ai accès. (Même là, en écrivant de /bin/bash
, je suppose que tous les shells de type Bourne admettent l'option longue --version
, quand cela casse pour ksh par exemple .)
Je recherche un test simple qui pourrait être sans surveillance et incorporé dans une section Utilisation au début du script ou même avant de l'appeler.
shell-script
shell
array
Cbhihe
la source
la source
csh
n'est pas une coquille de bourne.tcsh
n'en est pas un non plus (c'estcsh
avec quelques bugs corrigés)$SHELL
c'est le shell préféré de l'utilisateur, tout comme$EDITOR
son éditeur de texte préféré. Cela n'a pas grand-chose à voir avec le shell en cours d'exécution.eval
L'utilisation de la sortie du$SHELL --version
code shell n'a pas de sens.Réponses:
En supposant que vous voulez limiter à Bourne , comme des coquillages (beaucoup d' autres interpréteurs tels que
csh
,tcsh
,rc
,es
ou desfish
réseaux de soutien , mais l' écriture d' un script compatible en même temps de Bourne comme des coquilles et celles -ci est difficile et généralement inutile car ils sont les interprètes pour tout autre et incompatibles), notez qu'il existe des différences importantes entre les implémentations.Les shells Bourne qui supportent les tableaux sont:
ksh88
(c'est le premier à implémenter des tableaux, ksh88 se trouve toujours commeksh
sur la plupart des Unités Commerciales traditionnelles où il sert également de basesh
)set -A array foo bar
ouset -A array -- "$var" ...
si vous ne pouvez pas garantir que$var
cela ne commencera pas par un-
ou+
.0
.a[1]=value
.a[5]=foo
fonctionnera même sia[0,1,2,3,4]
elles ne sont pas définies et les laissera non définies.${a[5]}
pour accéder à l'élément d'indice 5 (pas nécessairement le 6ème élément si le tableau est clairsemé). L'5
il peut y avoir une expression arithmétique.${#a[@]}
est le nombre d'éléments attribués dans le tableau (et non le plus grand indice attribué).[[ -n "${a[i]+set}" ]]
).$a
est le même que${a[0]}
. C'est-à-dire que les tableaux étendent en quelque sorte les variables scalaires en leur donnant des valeurs supplémentaires.pdksh
et dérivés (c'est la base deksh
et parfoissh
de plusieurs BSD et était la seule implémentation ksh open source avant que la source ksh93 ne soit libérée):Surtout comme
ksh88
mais notez:set -A array -- foo bar
(ce--
n'était pas nécessaire là-bas).${#a[@]}
est un plus l'indice du plus grand indice attribué. (a[1000]=1; echo "${#a[@]}"
génère 1001 même si le tableau n'a qu'un seul élément.mksh
ont quelques opérateurs supplémentaires inspirés debash
,ksh93
ouzsh
comme les affectations à laa=(x y)
,a+=(z)
,${!a[@]}
pour obtenir la liste des indices attribués.zsh
.zsh
les tableaux sont généralement mieux conçus et prennent le meilleur deksh
et lescsh
tableaux. Ils sont similairesksh
mais avec des différences importantes:ksh
émulation), ce qui est cohérent avec le tableau Bourne (les paramètres de position $ @, quizsh
expose également comme son tableau $ argv) et lescsh
tableaux.$a
n'est pas identique à${a[0]}
mais s'étend aux éléments non vides du tableau ("${a[@]}"
pour tous les éléments comme dansksh
).a[5]=1
fonctionne mais affecte tous les éléments de 1 à 4 à la chaîne vide s'ils n'ont pas été affectés. Donc${#a[@]}
(identique à${#a}
celui dans ksh la taille de l'élément de l'indice 0) est le nombre d'éléments dans le tableau et le plus grand indice attribué.a=(x y)
.set -A a x y
fonctionne également, maisset -A a -- x y
n'est pas pris en charge sauf dans l'émulation ksh (ce--
n'est pas nécessaire dans l'émulation zsh).ksh93
. (décrivant ici les dernières versions).ksh93
, longtemps considéré comme expérimental, peut maintenant être trouvé dans de plus en plus de systèmes maintenant qu'il a été publié sous le nom de FOSS. Par exemple, c'est le/bin/sh
(où il a remplacé le shell Bourne/usr/xpg4/bin/sh
, le shell POSIX est toujours basé surksh88
) etksh
deSolaris 11
. Ses tableaux étendent et améliorent les ksh88.a=(x y)
peut être utilisé pour définir un tableau, mais puisqu'ila=(...)
est également utilisé pour définir des variables composées (a=(foo=bar bar=baz)
),a=()
est ambigu et déclare une variable composée, pas un tableau.a=((0 1) (0 2))
) et les éléments du tableau peuvent également être des variables composées (a=((a b) (c=d d=f)); echo "${a[1].c}"
).a=([2]=foo [5]=bar)
syntaxe peut être utilisée pour définir simultanément des tableaux clairsemés.zsh
, mais un grand nombre d'opérateurs pris en charge également pour manipuler les tableaux."${!a[@]}"
pour récupérer la liste des indices de tableau.bash
.bash
est l'enveloppe du projet GNU. Il est utilisé commesh
sur les versions récentes d'OS / X et certaines distributions GNU / Linux.bash
les tableaux imitent principalementksh88
ceux avec certaines fonctionnalités deksh93
etzsh
.a=(x y)
prise en charge.set -A a x y
non pris en charge.a=()
crée un tableau vide (aucune variable composée dansbash
)."${!a[@]}"
pour la liste des indices.a=([foo]=bar)
syntaxe prise en charge ainsi que quelques autres deksh93
etzsh
.bash
versions récentes prennent également en charge les tableaux associatifs en tant que type distinct.yash
. Il s'agit d'une implémentation POSIX sh relativement récente, propre et multi-octets. Pas largement utilisé. Ses tableaux sont une autre API propre similaire àzsh
a=(var value)
array
intégréearray -s a 5 value
modifier le 5 e élément échouerait si cet élément n'était pas assigné au préalable.${a[#]}
,${#a[@]}
étant la taille des éléments sous forme de liste.a=("$a")
redéfinir une variable scalaire en tant que tableau avant de pouvoir ajouter ou modifier des éléments.sh
.Donc, à partir de cela, vous pouvez voir que la détection de la prise en charge des baies, que vous pouvez faire avec:
n'est pas suffisant pour pouvoir utiliser ces tableaux. Vous devez définir des commandes d'encapsuleur pour affecter des tableaux dans leur ensemble et des éléments individuels, et assurez-vous de ne pas tenter de créer des tableaux clairsemés.
Comme
Et puis vous accédez à des éléments de tableau avec
"${a[$first_indice+n]}"
, toute la liste avec"${a[@]}"
et d' utiliser les fonctions d'emballage (array_elements
,set_array
,set_array_element
) pour obtenir le nombre d'éléments d'un tableau (en$REPLY
), définissez le tableau dans son ensemble ou attribuer des éléments individuels.Ne vaut probablement pas la peine. J'utilise
perl
ou limiter au tableau Bourne shell / POSIX:"$@"
.Si l'intention est de faire en sorte que certains fichiers soient fournis par le shell interactif d'un utilisateur pour définir des fonctions qui utilisent des tableaux en interne, voici quelques notes supplémentaires qui peuvent être utiles.
Vous pouvez configurer les
zsh
tableaux pour qu'ils ressemblent davantage à desksh
tableaux dans des étendues locales (dans des fonctions ou des fonctions anonymes).Vous pouvez également émuler
ksh
(améliorer la compatibilité avec lesksh
tableaux et plusieurs autres domaines) avec:Avec cela à l' esprit et vous êtes prêt à déposer soutien
yash
etksh88
et les anciennes versions depdksh
produits dérivés, et aussi longtemps que vous ne pas essayer de créer des tableaux rares, vous devriez être en mesure d'utiliser de manière cohérente:a[0]=foo
a=(foo bar)
(mais pasa=()
)"${a[#]}"
,"${a[@]}"
,"${a[0]}"
dans ces fonctions qui ont le
emulate -L ksh
, tandis que l'zsh
utilisateur utilise toujours ses tableaux normalement la manière zsh.la source
Vous pouvez utiliser
eval
pour essayer la syntaxe du tableau:la source
ksh88
prend en charge les tableaux mais pasa=()
. Dansksh93
,a=()
déclare une variable composée, pas un tableau, sauf si la variable a été déclarée auparavant comme un tableau.yash
, tu ne fais pasa[5]=1
maisarray -s a 5 1
ksh93
composée m'a fait une surprise, cela vous dérangerait de me donner une partie de la documentation à ce sujet. J'ajoute1
au tableau pour le faire fonctionner.