-1

This is a follow up to this question;
I don't know why but I keep misunderstanding the following code, although I try very hard to understand it:

function read_and_verify  {
    read -p "$1:" tmp1
    read -p "$2:" tmp2
    if [ "$tmp1" != "$tmp2" ]; then
        echo "Values unmatched. Please try again."; return 2
    else
        read "$1" <<< "$tmp1"
    fi
}

read_and_verify domain "Please enter the domain of your web application twice" 
read_and_verify dbrootp "Please enter the app DB root password twice" 
read_and_verify dbuserp "Please enter the app DB user password twice"

I misunderstand why is the $1 and $2 needed and henceforth why is the read "$1" <<< "$tmp1" needed.

What is actually happening in this comparison scenario?

2 Answers2

2

read -p "$1:" tmp1 and read -p "$2:" tmp2 read a line of input from the user each, using the first ($1) and second ($2) arguments to the function as prompts. The results are stored in tmp1 and tmp2. Then, if they are equal, the value from tmp1 is read into a variable named by the function's first argument with read "$1" <<< "$tmp1"

So, what you get with read_and_verify domain "Please enter the domain of your web application twice" is something that looks like this, with the user's input in italics:

domain:foo
Please enter the domain of your web application twice:foo

And then, the value entered is stored in the variable domain; running echo "$domain" after the above shows foo.

I misunderstand why is the $1 and $2 needed and henceforth why is the read "$1" <<< "$tmp1" needed.

$1 and $2 are used as prompts to the user, and $1 is also used to pass the name of the result variable to the function. This makes the first prompt a bit odd. It might be better to use something more descriptive, e.g.:

read -p "Please enter value for '$1': " tmp1
read -p "Please repeat the value to verify: " tmp2

Or to use the message passed in $2 for both prompts like the answer to your other question does.

read "$1" <<< "$tmp1" is also somewhat odd, in that usually you'd be able to just assign the value from one variable to another. Here, though, the problem is that $1 contains the name of a variable, so we need an indirect assignment. In Bash 4.3 and later, we could use a name reference for that:

declare -n ref="$1"
ref=$tmp1

So, the whole function might be better written like so:

#!/bin/bash
function read_and_verify  {
    read -p "Please enter value for '$1': " tmp1
    read -p "Please repeat the value to verify: " tmp2
    if [ "$tmp1" != "$tmp2" ]; then
        echo "Values unmatched. Please try again."; return 2
    else
        declare -n ref="$1"
        ref=$tmp1
    fi
}

(note that this doesn't use the second argument.)

ilkkachu
  • 138,973
0

read_and_verify is a function, in that context $1 is the first argument (here you invoke it with one of domain, dbrootp or dbuserp) and $2 is the second argument (the strings following each of those options in the invocations). If we expand it for invocation one:

function read_and_verify  {
    read -p "domain:" tmp1
    read -p "Please enter the domain of your web application twice:" tmp2
    if [ "$tmp1" != "$tmp2" ]; then
        echo "Values unmatched. Please try again."; return 2
    else
        read "domain" <<< "$tmp1"
    fi
}

And that is what $1 and $2 are doing in your function.