Call function from function into remote host through bash script is not working

184 views Asked by At

I am writing a bash script to log in the remote host and call multiple functions through it. Calling install_prelibrary from ssh remote script and calling other two functions from this. Below is my script:

#!/bin/bash

source ~/shell/config.sh

install_prelibrary () {
  wget https://github.com/EOSIO/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-18.04_amd64.deb --no-check-certificate > /dev/null 2>&1;
  if [ $? -ne 0 ]; then
                printf "\n\nError downloading Ubuntu Binary file\n\n"
                exit 0;
  else 
                install_cdt
                create_wallet_and_keys
  fi
}

install_cdt(){
   #some commands
}
create_wallet_and_keys(){
   #some commands
}

SCRIPT="$(cat ~/shell/config.sh) ; $(declare -f) ; install_prelibrary"
for i in ${!genesishost[*]} ; do
        printf "\t=========== node ${genesishost[i]} ===========\n\n"
        SCR=${SCRIPT/PASSWORD/${password}}
        sshpass -p ${password} ssh -l ${username} ${genesishost[i]} "${SCR}"
done

config.sh

#!/bin/bash

username=abc
password=abc
genesishost=(192.168.*.*);

When I run this script using bash main.sh, first of all, create_wallet_and_keys is getting called. I don't know why? As I am not calling this function manually anywhere. Followed by install_prelibrary and then install_cdt. Calling install_cdt from install_prelibrary is ok but create_wallet_and_keys gives error command not found. Why create_wallet_and_keys is not called on the remote host like other functions? I want the very first function to be called on a remote host is install_prelibrary and then call other two from this function. Please correct me.

2

There are 2 answers

0
tripleee On BEST ANSWER

Without seeing exactly what the generated script looks like, it's not really possible to troubleshoot this.

But I would instead break up your logic into a script which gets copied to the destination and executed there, and a simple script which does the copying and evaluation.

#!/bin/bash

script=$(cat <<\____HERE
install_prelibrary () {
  # Notice also refactoring; comments below
  if wget https://github.com/EOSIO/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-18.04_amd64.deb --no-check-certificate > /dev/null 2>&1; then
    : pass
  else
    rc=$?
    # Write errors to standard error, exit with an actual failure code
    printf "Error downloading Ubuntu Binary file\n" >&2
    exit $rc
  fi
  install_cdt
  create_wallet_and_keys
}

install_cdt(){
   #some commands
}
create_wallet_and_keys(){
   #some commands
}
____HERE
)
SCRIPT="$(cat ~/shell/config.sh); $script; install_prelibrary"
for i in ${!genesishost[*]} ; do
        printf "\t=========== node ${genesishost[i]} ===========\n\n"
        SCR=${SCRIPT/PASSWORD/"$password"}
        sshpass -p "$password" ssh -l "$username" "${genesishost[i]}" "${SCR}"
done

If you need to evaluate the functions locally, too, it's not too hard to have the script read itself; or simply store the code in an external file and source that as well as reading it into a variable.

0
Hek Sahiti On

Try reordering your functions

#!/bin/bash

source ~/shell/config.sh

install_cdt(){
   #some commands
}
create_wallet_and_keys(){
   #some commands
}

install_prelibrary () {
  wget https://github.com/EOSIO/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-18.04_amd64.deb --no-check-certificate > /dev/null 2>&1;
  if [ $? -ne 0 ]; then
                printf "\n\nError downloading Ubuntu Binary file\n\n"
                exit 0;
  else 
                install_cdt
                create_wallet_and_keys
  fi
}

SCRIPT="$(cat ~/shell/config.sh) ; $(declare -f) ; install_prelibrary"
for i in ${!genesishost[*]} ; do
        printf "\t=========== node ${genesishost[i]} ===========\n\n"
        SCR=${SCRIPT/PASSWORD/${password}}
        sshpass -p ${password} ssh -l ${username} ${genesishost[i]} "${SCR}"
done

This way they will be called beneath the functions themselves.