Dans Bourne comme shell qui supporte les variables de tableau, nous pouvons utiliser une analyse pour vérifier si la variable est un tableau.
Toutes les commandes ci-dessous ont été exécutées après exécution a=(1 2 3)
.
zsh
:
$ declare -p a
typeset -a a
a=( 1 2 3 )
bash
:
$ declare -p a
declare -a a='([0]="1" [1]="2" [2]="3")'
ksh93
:
$ typeset -p a
typeset -a a=(1 2 3)
pdksh
et sa dérivée:
$ typeset -p a
set -A a
typeset a[0]=1
typeset a[1]=2
typeset a[2]=3
yash
:
$ typeset -p a
a=('1' '2' '3')
typeset a
Un exemple dans bash
:
if declare -p var 2>/dev/null | grep -q 'declare -a'; then
echo array variable
fi
Cette approche représente trop de travail et doit générer un sous-shell. L'utilisation d'un autre shell intégré comme =~
dans [[ ... ]]
ne nécessite pas de sous-shell, mais est toujours trop compliqué.
Existe-t-il un moyen plus facile d'accomplir cette tâche?
Réponses:
Je ne pense pas que vous puissiez le faire, et je ne pense pas que cela fasse vraiment de différence.
Cela fait la même chose dans
ksh93
etbash
. Il ressemble peut-être à tous variables soient des tableaux dans ces shells, ou au moins toute variable régulière à laquelle aucun attribut spécial n'a été attribué, mais je n'ai pas vérifié beaucoup de cela.Le
bash
manuel parle de comportements différents pour un tableau par rapport à une variable de chaîne lors de l'utilisation des+=
affectations, mais il couvre ensuite et déclare que le tableau se comporte uniquement différemment dans un contexte d'affectation composé .Il indique également qu'une variable est considérée comme un tableau si un indice a été affecté à une valeur - et inclut explicitement la possibilité d'une chaîne nulle. Ci-dessus, vous pouvez voir qu'une affectation régulière entraîne définitivement l'affectation d'un indice - et donc je suppose que tout est un tableau.
En pratique, vous pouvez éventuellement utiliser:
... pour localiser clairement les variables d'ensemble auxquelles un seul indice de valeur 0 a été affecté.
la source
${a[1]-not array}
peut faire la tâche, n'est-ce pas?bash
manuel: une variable de tableau est considérée comme définie si un indice a reçu une valeur. La chaîne nulle est une valeur valide. Si un indice est affecté, c'est un tableau par spécification. En pratique, non, car vous pouvez le fairea[5]=x
. Je suppose que ça[ 1 -eq "${#a[@]}" ] && [ -n "${a[0]+1}" ]
pourrait marcher.Donc, vous voulez effectivement juste la partie médiane
declare -p
sans les déchets autour d'elle?Vous pouvez écrire une macro telle que:
afin que vous puissiez faire:
(Une simple fonction ne fera pas l'affaire si vous voulez l'utiliser sur des variables fonctionnelles locales).
Avec des alias
la source
alias vartype="$VARTYPE"
... ou tout simplement pas définir du$VARTYPE
tout - cela devrait fonctionner, non? vous devriez seulement avoir besoin de cetteshopt
chosebash
car elle rompt avec les spécifications concernant l'alias
expansion dans les scripts.En zsh
la source
echo ${(t)var}
- être plus simple. Merci pour cela.Pour tester la variable var, avec
Il est possible de tester s'il existe plusieurs index de tableau:
Si la première valeur d'index n'est pas nulle:
La seule confusion difficile est quand il n'y a qu'une seule valeur d'index et que cette valeur est zéro (ou un).
Pour cette condition, il est possible d'utiliser un effet secondaire en essayant de supprimer un élément de tableau d'une variable qui n'est pas un tableau:
Cela fonctionne correctement pour bash:
Pour zsh, l'index peut avoir besoin d'être 1 (sauf si un mode compatible est actif).
Le sous-shell est nécessaire pour éviter l'effet secondaire de l'effacement de l'indice 0 de var.
Je n'ai trouvé aucun moyen de le faire fonctionner dans ksh.
Modifier 1
Cette fonction ne fonctionne que dans bash4.2 +
Modifier 2
Cela ne fonctionne également que pour bash4.2 +
Remarque: Cela donnera des faux positifs si var contient les chaînes testées.
la source
( unset "var[0]" 2>/dev/null; ) && echo "var is an array."
indique correctement que var est un tableau lorsque var a été défini survar=()
un tableau avec zéro élément. Il agit exactement égal à déclarer.grep -E
au lieu degrep -P
pour éviter la dépendance à GNU grep.-a
, comme ceci:declare -airl var='()'
. Par conséquent, le test grep fonctionnera .Pour bash , c'est un peu un hack (bien que documenté): essayez d'utiliser
typeset
pour supprimer l'attribut "array":(Vous ne pouvez pas faire cela dans
zsh
, cela vous permet de convertir un tableau en scalaire, dansbash
ce qui est explicitement interdit.)Donc:
Ou dans une fonction, en notant les mises en garde à la fin:
Notez l'utilisation de
typeset -g
(bash-4.2 ou version ultérieure), ceci est requis dans une fonction pour quetypeset
(syn.declare
) Ne fonctionne pas commelocal
et n'encombre pas la valeur que vous essayez d'inspecter. Cela ne gère pas non plus les types de fonction "variable", vous pouvez ajouter un autre test de branche en utilisanttypeset -f
si nécessaire.Une autre option (presque complète) consiste à utiliser ceci:
Il y a cependant un léger problème, un tableau avec un seul indice de 0 correspond à deux des conditions ci-dessus. C'est quelque chose que mikeserv fait également référence, bash n'a vraiment pas de distinction difficile, et une partie de cela (si vous vérifiez le Changelog) peut être blâmée sur ksh et compatible avec comment
${name[*]}
ou${name[@]}
se comporter sur un non-tableau.Une solution partielle est donc:
J'ai utilisé dans le passé une variation à ce sujet:
cela aussi a besoin d'un sous-shell.
Une autre technique peut-être plus utile est
compgen
:Ceci listera tous les tableaux indexés, cependant les tableaux associatifs ne sont pas traités spécialement (jusqu'à bash-4.4) et apparaissent comme des variables régulières (
compgen -A variable
)la source
typeset +a
signale également une erreur dans ksh. Pas en zsh, cependant.Réponse courte:
Pour les deux shells qui ont introduit cette notation (
bash
etksh93
) une variable scalaire est juste un tableau avec un seul élément .Aucun n'a besoin d'une déclaration spéciale pour créer un tableau. Juste l'affectation est suffisante, et une affectation simple
var=value
est identique àvar[0]=value
.la source
bash -c 'unset var; var=foo; typeset -p var'
. Est-ce que bash answer rapporte un tableau (nécessite un -a)?. Maintenant , comparez avec:bash -c 'unset var; var[12]=foo; typeset -p var'
. Pourquoi y a-t-il une différence?. R: Le shell maintient (pour le meilleur ou pour le pire) une notion dont les vars sont des scalaires ou des tableaux. Le shell ksh mélange les deux concepts en un seul.La fonction intégrée de
array
yash possède certaines options qui ne fonctionnent qu'avec des variables de tableau. Exemple: l'-d
option signalera une erreur sur une variable non-tableau:Nous pouvons donc faire quelque chose comme ceci:
Cette approche ne fonctionnera pas si la variable tableau est en lecture seule . Essayer de modifier une variable en lecture seule conduisant à une erreur:
la source
la source