105 votes

Tableaux associatifs : erreur "declare : -A : option non valide"

J'ai écrit un script qui utilise des tableaux associatifs dans bash (v 4).

Cela fonctionne bien sur ma machine locale qui utilise 4.1.5(1)-release .

Sur la machine de production, en utilisant 4.1.0(1)-release la ligne suivante, qui déclare le tableau assoc, échoue :

declare -A uniqjars

avec le message :

/script.sh: line 11: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]

J'avais l'impression qu'il s'agissait d'une fonctionnalité générale de bash 4 ?

Dans le manuel de bash sur la machine de production, il est question de l'utilisation de -A Je suppose donc qu'il debe travail.

Les tableaux associatifs sont créés à l'aide de declare -A _name_ .

Je peux confirmer que le script utilise la bonne version de bash en imprimant la valeur de echo 'bash -version .

Que pourrais-je faire de mal ?

60voto

Richard H Points 11693

Assurez-vous que la version de bash invoquée comme interprète au début de votre shell script ( #!/bin/bash ou autre) est également la version 4. Si vous faites :

bash --version

et qu'il vous donne la v4, faites un which bash pour vérifier son emplacement.

60voto

Benjamin W. Points 19035

Ce qui suit semble être un scénario typique sur macOS après l'installation d'une nouvelle Bash avec Homebrew :

  • /bin/bash est l'ancienne version de Bash, 3.2
  • /usr/local/bin/bash est le nouveau Bash qui connaît les tableaux associatifs (4.0 ou plus récent)
  • type bash pointe vers /usr/local/bin/bash y bash --version est le nouveau (parce qu'il se résout en /usr/local/bin/bash --version )

Cependant, les scripts avec un #!/bin/bash qui sont exécutées avec ./script utilisera l'ancien Bash (le scénario de la question). Les solutions sont les suivantes :

  • Appeler le script avec bash script : le nouveau Bash sera utilisé. Inconvénient : il faut toujours l'appeler comme ça.
  • Remplacer la ligne shebang par #!/usr/local/bin/bash . Inconvénient : sur de nombreux systèmes, il n'y a pas de Bash in /usr/local/bin et votre script n'est plus portable.
  • Remplacer la ligne shebang par #!/usr/bin/env bash . Ceci utilisera le premier bash dans votre PATH qui devrait être le nouveau. C'est assez portable ; le seul inconvénient est que vous ne savez pas exactement quel Bash sera exécuté.

Voir aussi ces questions-réponses :

45voto

meigrafd Points 499

Voici une solution de contournement, si vous voulez utiliser les caractères comme index de tableau avec bash v3 :

array=(
    'hello::world.'
    'nice::to meet you'
)

for index in "${array[@]}" ; do
    KEY="${index%%::*}"
    VALUE="${index##*::}"
    echo "$KEY - $VALUE"
done

Sortie :

hello - world.
nice - to meet you

18voto

khancell Points 121

Voici comment obtenir la mise à jour bash sous OS X, vous devez installer brew et ensuite bash .

$ /bin/bash --version    
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin14)

$ brew install bash    
... install

$ /usr/local/bin/bash --version    
GNU bash, version 4.3.46(1)-release (x86_64-apple-darwin14.5.0)

9voto

KeithJ Points 151

meigrafd La réponse de l'auteur a résolu mon problème, donc si j'utilise un shebang incorrect ou si je suis encore sous bash version 3, ce qui suit m'a permis de retourner une valeur basée sur la clé qui lui est associée :

array=(
    'hello::world.'
    'nice::to meet you'
)

for index in "${array[@]}" ; do
  KEY="${index%%::*}"
  VALUE="${index##*::}"
  if [ "$KEY" == "nice" ]; then
    echo "$VALUE"
    break
  fi
done

La valeur obtenue est "pour vous rencontrer".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X