0

I am writing bash script given below (Please ignore the capital letters variable names, this is just my test file):

#!/bin/bash

create_nodes_directories(){
HOSTS=(192.168.110.165 192.168.110.166 192.168.110.167)
accounts=('accountnum11' 'accountnum12' 'accountnum13')
for i in "${!HOSTS[@]}"; do
        read -r curhost _ < <(hostname -I)
        printf 'Enter the key pair for the %s node\n' "${accounts[i]}"
        printf "Enter public key\n"
        read -r EOS_PUB_KEY
        printf "Enter private key\n"
        read -r EOS_PRIV_KEY
        PRODUCER=${accounts[i]}

        args=()
        args+=("$curhost")

        for j in "${!HOSTS[@]}"; do
                if [[ "$i" != "$j" ]]; then
                        args+=("${HOSTS[$j]}")
                else
                        continue;

                fi
        done
        #echo 'Array before test:'"${args[*]}"
        create_genesis_start_file "$EOS_PUB_KEY" "$EOS_PRIV_KEY" "${HOSTS[$i]}" "$PRODUCER" args
        create_start_file "$EOS_PUB_KEY" "$EOS_PRIV_KEY" "${HOSTS[$i]}" "$PRODUCER" args
done
}
            
create_genesis_start_file(){
        EOS_PUB_KEY=$1
        EOS_PRIV_KEY=$2
        CURRENTHOST=$3
        PRODUCER=$4
        peerags="$5[@]"
        peers=("${!peerags}")

        echo 'Genesis Currenthost is:'"$CURRENTHOST"
        #echo "${peers[*]}"
        VAR=""
        length=${#peers[@]}
        last=$((length - 1))

        for i in "${!peers[@]}" ; do

                if [[ "$i" == "$last" ]]; then
                        VAR+="--p2p-peer-address ${peers[$i]}:8888 \\"
                else
                        VAR+=$"--p2p-peer-address ${peers[$i]}:8888 \\"$'\n\t'
                fi
        done
}

create_start_file(){
        EOS_PUB_KEY=$1
        EOS_PRIV_KEY=$2
        CURRENTHOST=$3
        PRODUCER=$4
        peerags="$5[@]"
        peers=("${!peerags}")

        echo 'Start file Currenthost is:'"$CURRENTHOST"
        #echo "${peers[*]}"
}

create_nodes_directories

For every iteration of the first for loop, I am displaying the third argument $CURRENTHOST which is passed to functions create_genesis_start_file and create_start_file. For first iteration, output is:

Genesis Currenthost is:192.168.110.165
Start file Currenthost is:192.168.110.167

Second iteration:

Genesis Currenthost is:192.168.110.166
Start file Currenthost is:192.168.110.167

Third iteration,

Genesis Currenthost is:192.168.110.167
Start file Currenthost is:192.168.110.167

Genesis Currenthost is as expected and Start file Currenthost should be same with it. I am not getting why the Start file Currenthost is always set as 192.168.110.167. If I remove the below code from create_genesis_start_file it is working fine:

VAR=""
            length=${#peers[@]}
            last=$((length - 1))
    
            for i in "${!peers[@]}" ; do
    
                    if [[ "$i" == "$last" ]]; then
                            VAR+="--p2p-peer-address ${peers[$i]}:8888 \\"
                    else
                            VAR+=$"--p2p-peer-address ${peers[$i]}:8888 \\"$'\n\t'
                    fi
            done

I am not getting the exact problem why the variable value is getting changed? Please help.

2
  • 2
    You're using the variable i in both the main for i in "${!HOSTS[@]}" loop and also in the create_genesis_start_file function, and the function is stepping on the value partway through the loop. To avoid the conflict, either use a different variable name in the two places, or declare it local in the function (or both). Commented Nov 10, 2020 at 7:28
  • oh yes, My bad! Thank you. Problem solved. Commented Nov 10, 2020 at 7:31

1 Answer 1

1

The "$5[@]" looks odd to me. You can't use a scalar $5 as if it were an array.

It seems that you want to pass a whole array as parameter. Since bash does not have a native way to do this, I suggest that on the calling side, you pass "${args[@]}" as parameter, and inside your function, you do a

shift 4
peers=( "$@" )

Another possibility, which however violates the idea of encapsulation, is to treet peers as a global variable, which is accessible to all functions. With this approach, you would on the caller side collect the information already in the variable peers instead of args.

From a programming style, global variables (accross function boundaries) are usually disliked for good reasons, but in my personal opinion, if you just do simple shell scripting, I would find it an acceptable solution.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.