Вызов функции из функции на удаленный хост через скрипт bash не работает

#bash #function #shell #remote-host

#bash #функция #оболочка #удаленный хост

Вопрос:

Я пишу скрипт bash для входа в удаленный хост и вызова нескольких функций через него. Вызов install_prelibrary из удаленного скрипта ssh и вызов двух других функций из этого. Ниже приведен мой сценарий:

 #!/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>amp;1;
  if [ $? -ne 0 ]; then
                printf "nnError downloading Ubuntu Binary filenn"
                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]} ===========nn"
        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.*.*);
  

Когда я запускаю этот скрипт, используя bash main.sh , в первую очередь, create_wallet_and_keys вызывается. Я не знаю, почему? Поскольку я нигде не вызываю эту функцию вручную. Затем install_prelibrary и затем install_cdt . Вызов install_cdt из install_prelibrary в порядке, но create_wallet_and_keys выдает ошибку command not found . Почему create_wallet_and_keys не вызывается на удаленном хосте, как другие функции?
Я хочу, чтобы самая первая функция вызывалась на удаленном хосте install_prelibrary , а затем вызывала две другие из этой функции.
Пожалуйста, поправьте меня.

Комментарии:

1. У вас есть длинная строка вариантов этого вопроса, и на каждом перекрестке вам говорили, что этот подход ошибочен. Простое и понятное решение — скопировать файл сценария на удаленный хост, а затем выполнить его там.

2. Я попробовал это SCRIPT="$(cat ~/shell/config.sh) ; ‘bash -s’ < ~/shell/build/main.sh ; $(declare -f) ; install_prelibrary" . Копирование файла, но все равно он выполняется create_wallet_and_keys первым.

Ответ №1:

Не видя точно, как выглядит сгенерированный скрипт, на самом деле невозможно устранить неполадки.

Но вместо этого я бы разделил вашу логику на скрипт, который копируется в пункт назначения и выполняется там, и простой скрипт, который выполняет копирование и оценку.

 #!/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>amp;1; then
    : pass
  else
    rc=$?
    # Write errors to standard error, exit with an actual failure code
    printf "Error downloading Ubuntu Binary filen" >amp;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]} ===========nn"
        SCR=${SCRIPT/PASSWORD/"$password"}
        sshpass -p "$password" ssh -l "$username" "${genesishost[i]}" "${SCR}"
done
  

Если вам также нужно оценивать функции локально, не так уж сложно заставить скрипт прочитать сам; или просто сохраните код во внешнем файле source , а также считайте его в переменную.

Ответ №2:

Попробуйте изменить порядок ваших функций

 #!/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>amp;1;
  if [ $? -ne 0 ]; then
                printf "nnError downloading Ubuntu Binary filenn"
                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]} ===========nn"
        SCR=${SCRIPT/PASSWORD/${password}}
        sshpass -p ${password} ssh -l ${username} ${genesishost[i]} "${SCR}"
done
  

Таким образом, они будут вызываться под самими функциями.