#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
Таким образом, они будут вызываться под самими функциями.