#1 Le 19/05/2008, à 16:43
- Capashen
[Bash] Passer d'un argument à un nom de variable
Bonjour,
Je suis en train de coder un petit script bash, et je suis totalement coincé.
J'ai une fonction et je passe en argument un string "NOM_VAR".
J'aimerai ensuite faire NOM_VAR="truc"
Je suis complètement perdu entre les #,{,",', etc
Je n'arrive pas à créer le nom de la variable en fonction du string en argument, je penses avoir essayé toutes les combinaisons de #{"', sauf la bonne
En vous remerciant,
Capashen
Dernière modification par Capashen (Le 19/05/2008, à 16:47)
Hors ligne
#2 Le 19/05/2008, à 17:02
- Ultandir
Re : [Bash] Passer d'un argument à un nom de variable
Peut tu expliquer plus précisément ce que tu souhaite faire voir poster un petit peu de code?
Fedora Cambridge i386
Zenwalk 5.2
-------------
Il y a 10 types de personnes : celles qui connaissent le binaire, et celles qui ne le connaissent pas.
Hors ligne
#3 Le 19/05/2008, à 17:10
- Capashen
Re : [Bash] Passer d'un argument à un nom de variable
Voici mon script.
Ligne 126, j'appelle une fonction générique qui à partir de 3 champs renvoi la version d'un programme.
Exemple, pour trouver le nom de code d'ubuntu :
search_generic "nom de code de l'os" "lsb_release -c -s" 's/\(.*\)/\1/'
OS_NAME_CODENAME=`cat $RESULTS`
"nom de code de l'os" -> utilisé pour l'IHM
"lsb_release -c -s" -> pour récuperer la version
's/\(.*\)/\1/' -> pour récuperer uniquement le numéro de version (ici en fait c'est obsolete
Je voudrais passer en 4ème argument "OS_NAME_CODENAME", pour que ma fonction générique utilise directement la variable sans passer par un fichier... le problème et que je n'arrive pas à passer de l'argument à un nom de variable utilisable... Je peux aussi passer par une variable temporaire, mais ce n'est pas aussi propre que de passer directement la bonne variable en argument.
Voici le code complet
#!/bin/bash
############################
# Settings
############################
#Log files for stdout and temporary results
PWD=`pwd`
STDERR="${PWD}/log_errors"
RESULTS="${PWD}/log_results"
# Clear log files
echo "" > $STDERR
echo "" > $RESULTS
# Set default mode
INTERACTIVE_MODE=""
MANUAL_MODE="False"
# Set default label
NO_SEARCH="-"
NO_FOUND="\Z1\ZrAbsent\Zn"
NO_GOOD="Erreur"
############################
# Design
############################
# For title of box
TITLEBOX="\Zr\Zb\Z3"
# For backtitle
BACKTITLE=" \Z3VersusMind.eu\Zn - \Z7SystemAnalystMind 0.1\Zn"
# For title
TITLE="\Z7"
# End all styles
ENDSTYLE="\Zn"
############################
# Labels
############################
OK="OK"
YES="Oui"
NO="Non"
CANCEL="Annuler"
ACTIF="\Zb\Z2\Zr ACTIF \Zn"
INACTIF="\Zb\Z1\Zr INACTIF \Zn"
############################
# Welcome menu
# informations and select INTERACTIV or NO INTERACTIV mode
############################
menu_welcome()
{
./dialog --colors --yes-label "Non intéractif" --no-label "Intéractif" --backtitle "$BACKTITLE" --title "$TITLEBOX Bienvenue dans l'assistant d'installation ${ENDSTYLE}" \
--yesno "
${TITLE}Nom du script${ENDSTYLE} : SystemAnalystMind
${TITLE}Description${ENDSTYLE} : Générateur de fichier de conf.
${TITLE}Version${ENDSTYLE} : Pré-Alpha 0.1
${TITLE}Auteur${ENDSTYLE} : Pierre FREUND, VersusMind
Dans quel mode désirez vous démarrarer le script ?
" 12 70 \
2>> "$STDERR"
}
############################
# Main menu
# Select research in menu and execute function
############################
menu_main()
{
while (true); do
# Generate string for Manual/Interactiv mod
if [ $MANUAL_MODE == "False" ]; then
STRING_MANUAL=$INACTIF
elif [ $MANUAL_MODE == "True" ]; then
STRING_MANUAL=$ACTIF
fi
if [ $INTERACTIV_MODE == "False" ]; then
STRING_INTERACTIF=$INACTIF
elif [ $INTERACTIV_MODE == "True" ]; then
STRING_INTERACTIF=$ACTIF
fi
# Generate IHM (menu)
./dialog --no-cancel --ok-label "$OK" --colors --title "$TITLEBOX Menu général ${ENDSTYLE}" --backtitle "$BACKTITLE" \
--menu "$STRING_INTERACTIF Mode interactif
$STRING_MANUAL Mode manuel
${TITLE}Distribution${ENDSTYLE} : $OS_NAME_DISTRIBUTOR ${TITLE}Version${ENDSTYLE} : $OS_NAME_RELEASE ${TITLE}Code${ENDSTYLE} : $OS_NAME_CODENAME
${TITLE}Hardware${ENDSTYLE} : $OS_MACHINE ${TITLE}Network${ENDSTYLE} : $OS_NETWORK_NODE_HOSTNAME
${TITLE}Kernel name${ENDSTYLE} : $OS_KERNEL_NAME ${TITLE}Release${ENDSTYLE} : $OS_KERNEL_RELEASE
${TITLE}Processeur${ENDSTYLE} : $OS_PROCESSOR ${TITLE}Plateforme${ENDSTYLE} : $OS_HARDWARE_PLATFORM
${TITLE}Postfix${ENDSTYLE} : $POSTFIX ${TITLE}Postfix admin${ENDSTYLE} : $POSTFIX_ADMIN
${TITLE}Dovecot${ENDSTYLE} : $DOVECOT ${TITLE}Apache${ENDSTYLE} : $APACHE
${TITLE}Mysql${ENDSTYLE} : $MYSQL ${TITLE}PostgreSQL${ENDSTYLE} : $POSTGRESQL
${TITLE}Perl${ENDSTYLE} : $PERL ${TITLE}Php${ENDSTYLE} : $PHP
${TITLE}Ssh${ENDSTYLE} : $SSH
" 40 70 25 \
"" "Recherches" \
"" "" \
1 "Lancer toutes les recherches" \
2 "OS" \
3 "Postfix" \
4 "Postfix admin" \
5 "Dovecot" \
6 "Mysql" \
7 "PostgreSQL" \
8 "Apache" \
9 "Perl" \
10 "PHP" \
11 "SSH" \
"" "" \
"" "Autres opération" \
"" "" \
m "Basculer le mode manuel Actif/Inactif" \
i "Basculer le monde intéractif Actif/Inactif" \
e "Consulter le journal des erreurs" \
g "Génerer un rapport" \
c "Effacer les variables" \
q "Quitter le programme" 2> "$RESULTS"
choice=`cat $RESULTS`
case $choice in
1)
;;
2)
search_generic "nom du kernel" "uname -s" 's/\(.*\)/\1/'
OS_KERNEL_NAME=`cat $RESULTS`
search_generic "hostname network" "uname -n" 's/\(.*\)/\1/'
OS_NETWORK_NODE_HOSTNAME=`cat $RESULTS`
search_generic "version du kernel" "uname -r" 's/\(.*\)/\1/'
OS_KERNEL_RELEASE=`cat $RESULTS`
search_generic "architecture" "uname -m" 's/\(.*\)/\1/'
OS_MACHINE=`cat $RESULTS`
search_generic "processeur" "uname -p" 's/\(.*\)/\1/'
OS_PROCESSOR=`cat $RESULTS`
search_generic "plateforme" "uname -i" 's/\(.*\)/\1/'
OS_HARDWARE_PLATFORM=`cat $RESULTS`
search_generic "distribution" "lsb_release -i -s" 's/\(.*\)/\1/'
OS_NAME_DISTRIBUTOR=`cat $RESULTS`
search_generic "release de l'os" "lsb_release -r -s" 's/\(.*\)/\1/'
OS_NAME_RELEASE=`cat $RESULTS`
search_generic "nom de code de l'os" "lsb_release -c -s" 's/\(.*\)/\1/'
OS_NAME_CODENAME=`cat $RESULTS`
;;
3)
search_generic "de Postfix" "postconf mail_version" 's/^mail_version = \([0-9.]*\).*$/\1/'
POSTFIX=`cat $RESULTS`
;;
4)
search_generic "de Postfix-admin" "postconf mail_version" 's/^mail_version = \([0-9.]*\).*$/\1/'
POSTFIX=`cat $RESULTS`
;;
5)
;;
6)
search_generic "de MySQL" "mysql --version" 's/^.*Distrib \([0-9a-z.]*\).*$/\1/'
MYSQL=`cat $RESULTS`
;;
7)
;;
8)
search_generic "d'Apache" "apache2 -v" 's/^.*Apache\/\([0-9.]*\).*$/\1/'
APACHE=`cat $RESULTS`
;;
9)
search_generic "de Perl" "perl -v" 's/^.*This is perl, v\([0-9.]*\).*$/\1/'
PERL=`cat $RESULTS`
;;
10)
search_generic "de PHP" "php -v" 's/^PHP \([0-9.]*\).*$/\1/'
PHP=`cat $RESULTS`
;;
11)
search_ssh
;;
m)
manual_switch
;;
i)
interactiv_switch
;;
e)
display_errors
;;
g)
generate_report
;;
c)
clear_vars
;;
q)
clear
exit 0
;;
esac
done
}
############################
# Generic function for searching version number
# $1 = string for prompt
# $2 = command which diplay version ex : php -v
# $3 = sed to find only version string
############################
search_generic()
{
if [ $MANUAL_MODE == "True" ]; then
manual_results "$1"
if [ $? == 0 ]; then
SEARCH=`cat "$RESULTS"`
fi
else
SEARCH_VERSION=`$2 2>>$STDERR`
SEARCH_TEMP=`echo $SEARCH_VERSION | sed "$3" 2>>$STDERR`
if [ "${#SEARCH_TEMP}" = 0 ]; then
SEARCH_TEMP=$NO_FOUND
fi
if [ $INTERACTIV_MODE == "True" ]; then
confirm_results "$1" "$SEARCH_TEMP"
if [ $? == 0 ]; then
SEARCH=$SEARCH_TEMP
elif [ $? == 1 ]; then
SEARCH=$NO_GOOD
fi
else
SEARCH=$SEARCH_TEMP
fi
fi
echo $SEARCH > $RESULTS
}
############################
# Generate IHM for page which diplay errors
############################
display_errors()
{
CAT_ERROR=`cat $STDERR`
./dialog --colors --ok-label "$OK" --backtitle "$BACKTITLE" --title "$TITLEBOX Journal des erreurs ${ENDSTYLE}" \
--msgbox "$CAT_ERROR" 40 100 \
2>> "$STDERR"
}
############################
# Generate IHM "Is the result correct ?"
############################
confirm_results()
{
./dialog --colors --yes-label "$YES" --no-label "$NO" --backtitle "$BACKTITLE" --title "$TITLEBOX Demande de confirmation ${ENDSTYLE}" \
--yesno "Le script a trouvé ${TITLE}${2}${ENDSTYLE} comme ${TITLE}${1}${ENDSTYLE}.
$3
Confirmez vous ce résultat ?" 9 70 2>>$STDERR
}
############################
# Generate IHM for manual settings
############################
manual_results()
{
./dialog --colors --ok-label "$OK" --cancel-label "$CANCEL" --backtitle "$BACKTITLE" --title "$TITLEBOX Configuration manuelle ${ENDSTYLE}" \
--inputbox "Veuillez indiquer la version$TITLE $1 ${ENDSTYLE}." 10 50 2> "$RESULTS"
}
############################
# Array of vars
############################
list_vars()
{
list_software[0]=OS_KERNEL_NAME
list_software[1]=OS_NETWORK_NODE_HOSTNAME
list_software[2]=OS_KERNEL_RELEASE
list_software[3]=OS_MACHINE
list_software[4]=OS_PROCESSOR
list_software[5]=OS_HARDWARE_PLATFORM
list_software[6]=OS_NAME_DISTRIBUTOR
list_software[7]=OS_NAME_RELEASE
list_software[8]=OS_NAME_CODENAME
list_software[8]=POSTFIX
list_software[10]=POSTFIX_ADMIN
list_software[11]=DOVECOT
list_software[12]=MYSQL
list_software[13]=POSTGRESQL
list_software[14]=APACHE
list_software[15]=PERL
list_software[16]=PHP
}
############################
# Clear all vars
############################
#clear_vars()
#{
# OS_KERNEL_NAME=$NO_SEARCH
# OS_NETWORK_NODE_HOSTNAME=$NO_SEARCH
# OS_KERNEL_RELEASE=$NO_SEARCH
## OS_MACHINE=$NO_SEARCH
# OS_PROCESSOR=$NO_SEARCH
# OS_HARDWARE_PLATFORM=$NO_SEARCH
# OS_NAME_DISTRIBUTOR=$NO_SEARCH
# OS_NAME_RELEASE=$NO_SEARCH
# OS_NAME_CODENAME=$NO_SEARCH
#
# POSTFIX=$NO_SEARCH
# POSTFIX_ADMIN=$NO_SEARCH
# DOVECOT=$NO_SEARCH
# MYSQL=$NO_SEARCH
# POSTGRESQL=$NO_SEARCH
# APACHE=$NO_SEARCH
# PERL=$NO_SEARCH
# PHP=$NO_SEARCH
#}
clear_vars()
{
echo p;
}
############################
# Switch Interactiv mod
############################
interactiv_switch()
{
if [ $INTERACTIV_MODE == "False" ]; then
{
INTERACTIV_MODE="True"
MANUAL_MODE="False"
}
elif [ $INTERACTIV_MODE == "True" ]; then
{
INTERACTIV_MODE="False"
}
fi
}
############################
# Switch Manual mod
############################
manual_switch()
{
if [ $MANUAL_MODE == "False" ]; then
{
MANUAL_MODE="True"
INTERACTIV_MODE="False"
}
elif [ $MANUAL_MODE == "True" ]; then
{
MANUAL_MODE="False"
}
fi
}
############################
# Switch Manual mod
############################
############################
# Begin
############################
list_vars
echo "bbbbbbbbbblah"
#PHP=5
#version[$PHP]="bonjour"
#regexp[$PHP]="s/...:..../"
#commande[$PHP]="php -v";
#for software in ${list_software[*]}
#do
# echo "$software = ${$software}"
#done
#exit 1
clear_vars
menu_welcome
if [ $? == 0 ]; then
INTERACTIV_MODE="False"
elif [ $? == 1 ]; then
INTERACTIV_MODE="True"
fi
menu_main
############################
# End
############################
Dernière modification par Capashen (Le 19/05/2008, à 17:14)
Hors ligne
#4 Le 20/05/2008, à 07:03
- Ultandir
Re : [Bash] Passer d'un argument à un nom de variable
Tu ne peut pas a ma connaissance transformer un paramètre en nom de variable.
Si j'ai bien compris, si tu appel ton programme avec le paramètre "bonjour", tu veut qu'une variable dans ton programme ai pour nom "bonjour".
Pour ca deux facons de faire :
Soit par variable temporaire.
Soit, si tu sait d'avance quelles sont les possibilitées de noms, un tableau de noms de variables sur lequel tu test ( si le paramètre = ca, alors ....)
Fedora Cambridge i386
Zenwalk 5.2
-------------
Il y a 10 types de personnes : celles qui connaissent le binaire, et celles qui ne le connaissent pas.
Hors ligne
#5 Le 20/05/2008, à 08:16
- Capashen
Re : [Bash] Passer d'un argument à un nom de variable
Oui c'est ce que voulais faire...
Tant pis je vais passer par une variable temporaire.
Merci
Hors ligne
#6 Le 20/05/2008, à 08:30
- iuchiban
Re : [Bash] Passer d'un argument à un nom de variable
A la rigueur un tableau avec 2 colonnes :
+--------+------+
|variable|Valeur|
+--------+------+
Mais en shell, il te faut chercher dans le tableau la ligne correspondant à bonjour (par exemple) avant de récupérer la valeur.
(En Ruby, tu fais valeur=tab["bonjour"] et roulez jeunesse)
En TI Basic, il faut utiliser des indirections pour faire ce genre de chose, je sais pas si c'est faisable en shell.
http://abs.traduc.org/abs-5.3-fr/ch09s05.html
devrait pouvoir t'aider
Ouais bon non en fait, mais ça peut être utile
EDIT 3 :
Si j'ai bien compris, si tu appel ton programme avec le paramètre "bonjour", tu veut qu'une variable dans ton programme ai pour nom "bonjour".
donc mettons, si la creation de variable via paramètre fonctionne, tu lances :
script.sh bonjour
tu vas avoir une variable qui s'appelle bonjour.
Mais dans ton programme plus tard, pour récupérer la valeur de cette variable, tu dois savoir qu'elle s'appelle bonjour, donc tu as du stocker cette valeur quelque part, donc tu peux appeler directement via cette valeur pour récupérer la valeur de la valeur, d'ou la double redirection (\$$variable);
Donc soit comme te l'a proposé Ultandir, tu crées un tableau contenant les variables potentiellement utilisées (ici les noms de distrib Ubuntu Warty, Hoary, Breezy, Dapper, Edgy, Feisty, Gutsy, Hardy, Intrepid), soit variable temporaire ou à la rigueur, tu peux créer un fichier dans lequel tu stockes ta valeur, mais c'est lourd et pas très propre.
Dernière modification par iuchiban (Le 20/05/2008, à 08:57)
C'est depuis que Chuck Norris a laissé la vie sauve à un manchot que l'on dit que Linux est libre.
Chuck Norris n'a pas besoin d'éditer son premier message pour ajouter [Résolu]. Chuck Norris est toujours [Résolu], quoi qu'il arrive.
Hors ligne
#7 Le 20/05/2008, à 08:55
- Totor
Re : [Bash] Passer d'un argument à un nom de variable
Salut,
j'ai déjà eu un besoin similaire.
Affectation des variables
export nomVar=toto
export $nomVar=titi
Vérification manuelle
echo $nomVar
-->toto
echo $toto
-->titi
Affichage de la valeur de la variable dont le nom est la valeur de nomVar
eval "echo \$$nomVar"
-->titi
Pour affecter la valeur de la variable dont le nom est la valeur de nomVar dans une nouvelle variable
export valeur=$(eval "echo \$$nomVar")
echo $valeur
-->titi
je n'ai pas de debian sous la main mais j'ai testé sous une redhat et une solaris en bash.
Dans ton cas NOM_VAR est un paramètre de la fonction (admettons que ce soit le 1er), donc
#!/bin/bash
mafonction()
{
NOM_VAR=$1
export $NOM_VAR="truc"
}
export bonjour="rien"
mafonction bonjour
echo $bonjour
je pense que c'est ce que tu cherches
Dernière modification par Totor (Le 20/05/2008, à 11:47)
-- Lucid Lynx --
Hors ligne
#8 Le 25/06/2008, à 17:47
- Stéphane__
Re : [Bash] Passer d'un argument à un nom de variable
C'est ce que je cherchais aussi, merci bien :-)