En supposant que vous voulez limiter à Bourne , comme des coquillages (beaucoup d' autres interpréteurs tels que csh, tcsh, rc, esou des fishré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 comme kshsur la plupart des Unités Commerciales traditionnelles où il sert également de base sh)
- les tableaux sont unidimensionnels
- Les tableaux sont définis comme
set -A array foo barou set -A array -- "$var" ...si vous ne pouvez pas garantir que $varcela ne commencera pas par un -ou +.
- Les indices de tableau commencent à
0.
- Les éléments de tableau individuels sont affectés en tant que
a[1]=value.
- les tableaux sont clairsemés. Cela
a[5]=foofonctionnera même si a[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' 5il peut y avoir une expression arithmétique.
- la taille du tableau et l'indice sont limités (à 4096).
${#a[@]} est le nombre d'éléments attribués dans le tableau (et non le plus grand indice attribué).
- il n'y a aucun moyen de connaître la liste des indices attribués (à part tester les 4096 éléments individuellement avec
[[ -n "${a[i]+set}" ]]).
$aest 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.
pdkshet dérivés (c'est la base de kshet parfois shde plusieurs BSD et était la seule implémentation ksh open source avant que la source ksh93 ne soit libérée):
Surtout comme ksh88mais notez:
- Certaines anciennes implémentations ne prenaient pas en charge
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.
- dans les versions plus récentes, la taille du tableau n'est plus limitée (autrement que par la taille des entiers).
- les versions récentes de
mkshont quelques opérateurs supplémentaires inspirés de bash, ksh93ou zshcomme les affectations à la a=(x y), a+=(z), ${!a[@]}pour obtenir la liste des indices attribués.
zsh. zshles tableaux sont généralement mieux conçus et prennent le meilleur de kshet les cshtableaux. Ils sont similaires kshmais avec des différences importantes:
- les indices commencent à 1, pas à 0 (sauf en
kshémulation), ce qui est cohérent avec le tableau Bourne (les paramètres de position $ @, qui zshexpose également comme son tableau $ argv) et les cshtableaux.
- ils sont d'un type distinct des variables normales / scalaires. Les opérateurs s'appliquent différemment à eux et comme vous vous y attendez généralement.
$an'est pas identique à ${a[0]}mais s'étend aux éléments non vides du tableau ( "${a[@]}"pour tous les éléments comme dans ksh).
- ce sont des tableaux normaux, pas des tableaux clairsemés.
a[5]=1fonctionne 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é.
- les tableaux associatifs sont pris en charge.
- un grand nombre d'opérateurs pour travailler avec des tableaux est pris en charge, trop gros pour être répertorié ici.
- tableaux définis comme
a=(x y). set -A a x yfonctionne également, mais set -A a -- x yn'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é sur ksh88) et kshde Solaris 11. Ses tableaux étendent et améliorent les ksh88.
a=(x y)peut être utilisé pour définir un tableau, mais puisqu'il a=(...)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.
- les tableaux sont multidimensionnels (
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}").
- Une
a=([2]=foo [5]=bar)syntaxe peut être utilisée pour définir simultanément des tableaux clairsemés.
- Levée des limitations de taille.
- Pas dans la mesure de
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.
- les tableaux associatifs sont également pris en charge comme un type distinct.
bash. bashest l'enveloppe du projet GNU. Il est utilisé comme shsur les versions récentes d'OS / X et certaines distributions GNU / Linux. bashles tableaux imitent principalement ksh88ceux avec certaines fonctionnalités de ksh93et zsh.
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 dans bash).
"${!a[@]}" pour la liste des indices.
a=([foo]=bar)syntaxe prise en charge ainsi que quelques autres de ksh93et zsh.
- les
bashversions 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
- les tableaux ne sont pas rares
- Les indices de tableau commencent à 1
- défini (et déclaré) avec
a=(var value)
- éléments insérés, supprimés ou modifiés avec la fonction
arrayintégrée
array -s a 5 valuemodifier le 5 e élément échouerait si cet élément n'était pas assigné au préalable.
- le nombre d'éléments dans le tableau est
${a[#]}, ${#a[@]}étant la taille des éléments sous forme de liste.
- les tableaux sont un type distinct. Vous devez
a=("$a")redéfinir une variable scalaire en tant que tableau avant de pouvoir ajouter ou modifier des éléments.
- les tableaux ne sont pas pris en charge lorsqu'ils sont appelés en tant que
sh.
Donc, à partir de cela, vous pouvez voir que la détection de la prise en charge des baies, que vous pouvez faire avec:
if (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'
) > /dev/null 2>&1
then
array_supported=true
else
array_supported=false
fi
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
unset a
array_elements() { eval "REPLY=\"\${#$1[@]}\""; }
if (set -A a -- a) 2> /dev/null; then
set -A a -- a b
case ${a[0]}${a[1]} in
--) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=0;;
a) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=1;;
--a) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
ab) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
esac
elif (eval 'a[5]=x') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0
elif (eval 'a=(x) && array -s a 1 y && [ "${a[1]}" = y ]') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() {
eval "
$1=(\${$1+\"\${$1[@]}"'"})
while [ "$(($2))" -ge "${'"$1"'[#]}" ]; do
array -i "$1" "$2" ""
done'
array -s -- "$1" "$((1+$2))" "$3"
}
array_elements() { eval "REPLY=\${$1[#]}"; }
first_indice=1
else
echo >&2 "Array not supported"
fi
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 perlou 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 zshtableaux pour qu'ils ressemblent davantage à des kshtableaux dans des étendues locales (dans des fonctions ou des fonctions anonymes).
myfunction() {
[ -z "$ZSH_VERSION" ] || setopt localoption ksharrays
# use arrays of indice 0 in this function
}
Vous pouvez également émuler ksh(améliorer la compatibilité avec les kshtableaux et plusieurs autres domaines) avec:
myfunction() {
[ -z "$ZSH_VERSION" ] || emulate -L ksh
# ksh code more likely to work here
}
Avec cela à l' esprit et vous êtes prêt à déposer soutien yashet ksh88et les anciennes versions de pdkshproduits 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 pas a=())
"${a[#]}", "${a[@]}","${a[0]}"
dans ces fonctions qui ont le emulate -L ksh, tandis que l' zshutilisateur utilise toujours ses tableaux normalement la manière zsh.