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 if
… elif
… sequence.
Final note: use shellcheck.net to sanity-check your code.