2017-10-20 63 views
0

J'essaie d'attribuer une variable à un choix d'entrée rapide sans succès. Si l'utilisateur entre 1, je veux target_db_name = "database2". Mon code:Affectation d'une variable à une variable dans l'instruction if

while true; do 
    read -p "What is the table name?" table_name 
table_name=${table_name,,} 
    if hdfs dfs -test -e /foo/$table_name ; 
    then read -p "What is the target database you want to copy the 
“foo.${table_name}” table to? 

Your three options are: 
1) database1 
2) database2 
3) database3 

Type 1, 2, or 3: " target_db; 

(((Here is where I want to state if $target_db = "1" then target_db_name 
= "database1", if $target_db = "2" then target_db_name = "database2" etc...))) 

read -p "Would you like to begin the HDFS copy with the following configuration: 

Target Database: ${target_db_name} 
Table Name: ${table_name} 

Continue (Y/N):" 

else echo "Please provide a valid table name. 
Exiting this script" ; exit ; fi 

done 

J'ai essayé de créer une autre instruction if sans chance.

"....Type 1, 2, or 3: " target_db; 
else if $target_db = "1" then target_db_name = "edw_qa_history"; fi 
+0

S'il vous plaît montrer ce que vous avez essayé, afin que nous puissions vous expliquer ce que vous avez fait de mal. – Barmar

+0

Rappelez-vous que les assignations de variables dans 'bash' n'ont pas d'espace autour de' = '. – Barmar

+0

Et vous devriez probablement utiliser 'case' plutôt que' if'. – Barmar

Répondre

1

if $target_db = "1" then ne fonctionnera pas, car ce qui suit if doit être une commande, pas une expression de test. Maintenant, la commande la plus courante utilisée dans if instructions est [ (oui, c'est en fait un nom de commande, c'est aussi la commande test), qui prend une expression de test (et un crochet proche) comme arguments et réussit ou échoue selon que l'expression est vraie ou non. Donc, la syntaxe correcte serait quelque chose comme:

if [ "$target_db" = "1" ]; then 

Notez qu'il existe deux autres différences de ce que vous aviez: je mets des guillemets doubles autour de la référence variable (presque toujours une bonne idée, pour éviter peut analyse bizarreries) , et ajouté un point-virgule avant then (nécessaire pour indiquer où les arguments à la fin [ et la syntaxe du shell reprend). Je remarque également que vous avez des points-virgules à la fin de plusieurs lignes de votre script; ce n'est pas nécessaire, la fin de ligne suffit pour indiquer la fin d'une commande. C'est seulement si vous avez une autre commande (ou quelque chose comme then) sur la même ligne que vous avez besoin d'un point-virgule comme délimiteur. Cependant, comme @Barmar a souligné dans un commentaire, case serait probablement mieux qu'une liste de if et elif déclarations ici. case est conçu spécifiquement pour comparer une chaîne à une liste d'autres chaînes (ou modèles) et exécuter différentes choses en fonction de celle qui correspond. Il ressemble à ceci:

case "$target_db" in 
    1) target_db_name="database1" ;; 
    2) target_db_name="database2" ;; 
    3) target_db_name="database3" ;; 
    *) "Please provide a valid table name. Exiting this script" ; exit ;; 
esac 

Ici, le double-virgule est nécessaire, même à la fin d'une ligne, pour indiquer la fin de chaque cas. Notez également que le modèle * (le dernier cas) correspond à n'importe quoi, donc il fonctionne comme un else dans une séquence if ... elif ....

Note finale: utilisez shellcheck.net pour vérifier votre code.

+0

Merci beaucoup pour les informations utiles – user3508766

0

Vous n'avez pas besoin d'une instruction if pour mapper le nombre à un tableau; vous avez juste besoin d'un tableau.

db_names=(
    "datebase 1" 
    "database 2" 
    "database 3" 
) 

# ... 

target_db_name=${db_names[$target_db - 1]} 
if [[ -z $target_db_name ]]; then 
    exit 
fi