En supposant que vous voulez limiter à Bourne , comme des coquillages (beaucoup d' autres interpréteurs tels que csh
, tcsh
, rc
, es
ou des fish
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 comme ksh
sur 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 bar
ou set -A array -- "$var" ...
si vous ne pouvez pas garantir que $var
cela 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]=foo
fonctionnera 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' 5
il 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}" ]]
).
$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 de ksh
et parfois sh
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:
- 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
mksh
ont quelques opérateurs supplémentaires inspirés de bash
, ksh93
ou zsh
comme les affectations à la a=(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 de ksh
et les csh
tableaux. Ils sont similaires ksh
mais 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 zsh
expose également comme son tableau $ argv) et les csh
tableaux.
- 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.
$a
n'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]=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é.
- 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 y
fonctionne également, mais set -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é sur ksh88
) et ksh
de 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
. bash
est l'enveloppe du projet GNU. Il est utilisé comme sh
sur les versions récentes d'OS / X et certaines distributions GNU / Linux. bash
les tableaux imitent principalement ksh88
ceux avec certaines fonctionnalités de ksh93
et 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 ksh93
et zsh
.
- les
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
- 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
array
intégrée
array -s a 5 value
modifier 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 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 à des ksh
tableaux 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 ksh
tableaux 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 yash
et ksh88
et les anciennes versions de pdksh
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 pas a=()
)
"${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.