Skip to content
Advertisement

Assigning variable to a variable inside if statement

I am trying to assign a variable from a prompt input choice with no luck. If the user inputs 1, I want target_db_name = “database2”. My code:

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

I have tried creating another if statement with no luck.

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

Advertisement

Answer

if $target_db = "1" then won’t work, because what follows if must be a command, not a test expression. Now, the most common command used in if statements is [ (yes, that’s actually a command name; it’s synonymous with the test command), which takes a test expression (and a close bracket) as its arguments and succeeds or fails depending on whether the expression is true or not. So the correct syntax would be something like:

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

Note that there are two other differences from what you had: I put double-quotes around the variable reference (almost always a good idea, to avoid may parsing oddities), and added a semicolon before then (needed to indicate where the arguments to [ end and shell syntax resumes). I also notice you have semicolons at the end of many lines of your script; this isn’t necessary, the end-of-line is enough to indicate the end of a command. It’s only if you have another command (or something like then) on the same line that you need a semicolon as a delimiter.

HOWEVER, as @Barmar pointed out in a comment, case would probably be better than a list of if and elif statements here. case is intended specifically for comparing a string against a list of other strings (or patterns), and executing different things depending on which one it matches. It looks something like this:

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

Here, the double-semicolon is needed, even at the end of a line, to indicate the end of each case. Also, note that the * pattern (the last case) matches anything, so it functions like an else would in an ifelif … sequence.

Final note: use shellcheck.net to sanity-check your code.

Advertisement