211 votes

Comment obtenir la valeur d'une variable si le nom de la variable est stocké sous forme de chaîne de caractères ?

Comment récupérer la valeur d'une variable bash si le nom de la variable est une chaîne de caractères ?

var1="this is the real value"
a="var1"
Do something to get value of var1 just using variable a.

Contexte :

J'ai quelques AMI ( Image de la machine Amazon ) et je veux lancer quelques instances de chaque AMI. Dès que le démarrage est terminé, je veux configurer chaque instance en fonction de son type d'AMI. Je ne veux pas intégrer beaucoup de scripts ou de clés secrètes dans une AMI, j'ai donc préparé un scripts de démarrage généralisé et je l'ai placé dans le fichier S3 avec un lien accessible au public. Dans rc.local, je place un petit morceau de code qui récupère le script de démarrage et l'exécute. C'est tout ce que j'ai dans les AMI. Ensuite, chaque AMI accède à une configuration commune script qui s'applique à toutes les AMI et à des script spéciaux pour chacune d'entre elles. Ces script sont privés et nécessitent une URL signée pour y accéder.

Ainsi, lorsque je lance une instance d'une AMI (my_private_ami_1), je transmets une URL signée pour un autre fichier présenté sur S3 qui contient l'URL signée pour tous les scripts privés en termes de paires clé/valeur.

config_url="http://s3.amazo.../config?signature"
my_private_ami_1="http://s3.amazo.../ami_1?signature"
...

Lorsque le script de démarrage s'exécute, il télécharge le fichier ci-dessus et source c'est cela. Ensuite, il vérifie son type d'AMI et choisit la bonne configuration script pour lui-même.

ami\_type=GET AMI TYPE #ex: sets ami\_type to my\_private\_ami\_1
setup\_url=GET THE SETUP FILE URL BASED ON AMI\_TYPE # this is where this problem arises

J'ai donc maintenant un code générique qui peut déclencher des instances indépendamment de leur type d'AMI et les instances peuvent s'occuper d'elles-mêmes.

8voto

Alexandre Hamon Points 146

J'ai eu le même problème avec les tableaux, voici comment faire si vous manipulez aussi des tableaux :

array_name="ARRAY_NAME"
ARRAY_NAME=("Val0" "Val1" "Val2")

ARRAY=$array_name[@]
echo "ARRAY=${ARRAY}"
ARRAY=("${!ARRAY}")
echo "ARRAY=${ARRAY[@]}"
echo "ARRAY[0]=${ARRAY[0]}"
echo "ARRAY[1]=${ARRAY[1]}"
echo "ARRAY[2]=${ARRAY[2]}"

Le résultat sera :

ARRAY=ARRAY_NAME[@]
ARRAY=Val0 Val1 Val2
ARRAY[0]=Val0
ARRAY[1]=Val1
ARRAY[2]=Val2

2voto

user8150417 Points 13

Dans bash 4.3, le test '-v' pour les variables set a été introduit. Parallèlement, la déclaration "nameref" a été ajoutée. Ces deux caractéristiques, associées à l'opérateur d'indirection ( !), permettent d'obtenir une version simplifiée de l'exemple précédent :

get_value()
{
  declare -n var_name=$1
  if [[ -v var_name ]]
  then
    echo "${var_name}"
  else
    echo "variable with name <${!var_name}> is not set"
  fi
}

test=123
get_value test
123

test="\$(echo \"something nasty\")"
get_value test
$(echo "something nasty")

unset test
get_value test
variable with name <test> is not set

Cette approche est plus sûre car elle élimine la nécessité d'une "évaluation". Ce code a été vérifié sous bash 5.0.3(1).

1voto

ghostdog74 Points 86060

Les shells modernes supportent déjà les tableaux (et même les tableaux associatifs). Alors s'il vous plaît, utilisez-les, et utilisez moins d'eval.

var1="this is the real value"
array=("$var1")
# or array[0]="$var1"

puis lorsque vous voulez l'appeler, echo ${array[0]}

0voto

VFein Points 191

Sur la base de la réponse : https://unix.stackexchange.com/a/111627

###############################################################################
# Summary: Returns the value of a variable given it's name as a string.
# Required Positional Argument: 
#   variable_name - The name of the variable to return the value of
# Returns: The value if variable exists; otherwise, empty string ("").
###############################################################################
get_value_of()
{
    variable_name=$1
    variable_value=""
    if set | grep -q "^$variable_name="; then
        eval variable_value="\$$variable_name"
    fi
    echo "$variable_value"
}

test=123
get_value_of test
# 123
test="\$(echo \"something nasty\")"
get_value_of test
# $(echo "something nasty")

-1voto

MingalevME Points 136
VALUE=$(eval "echo \$$SOME_VAR_NAME")

Exemple

SSH_KEY_FILE_PATH_FOO="/tmp/key"
SSH_KEY_FILE_PATH_VAR_NAME_PREFIX="SSH_KEY_FILE_PATH"
SSH_KEY_FILE_PATH_VAR_NAME_SUFFIX="FOO"
SSH_KEY_FILE_PATH=$(eval "echo \$${SSH_KEY_FILE_PATH_VAR_NAME_PREFIX}_${SSH_KEY_FILE_PATH_VAR_NAME_SUFFIX}")
echo "$SSH_KEY_FILE_PATH"
/tmp/key

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