2014-01-15 4 views
5

Я пишу сценарий для восстановления репликации Master-Slave на множестве серверов. Проиграл в синтаксисе Баш пытается присвоить локальную переменную с результатом дистанционно управлял командой подстановки с локальными значениями:Как присвоить локальную переменную удаленной команде результат в сценарии bash?

function doRemote() { 
    ssh s1.domain.com <<ENDSSH 
     mysql -u root -pXXX --execute="DROP DATABASE db; CREATE DATABASE db;" 
     mysql -u root -pXXX --database=db < $WORKDIR$FILENAME 
     sudo rm -rf /var/log/mysql/db-bin.* 
     mysql -u root -pXXX --execute="FLUSH LOGS;" 
     CURRENT_LOG=`mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $1}'` 
     CURRENT_POS=`mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $2}'` 
     # ... 
ENDSSH 
} 

Две линии назначая CURRENT_ * переменные являются проблемой: команда mysql -u... запускается на выполнение локально, а не удаленный сеанс.

Просьба проконсультироваться о том, как удаленно запускать его, назначая локальную переменную с помощью команды удаленного mysql.

+1

сделал работу с остротами: 'CURRENT_LOG = $ (SSH s1.somain.com \t "MySQL -u корень -pXXX --execute = \" SHOW MASTER STATUS \» -AN | AWK ' {print \ $ 1} '")' – Serge

ответ

6

Try спасаясь ENDSSH, как показано ниже, так что переменная оценка происходит на удаленном узле:

ssh s1.domain.com <<\ENDSSH 
    # ... 
ENDSSH 
+0

+1. Вы также можете использовать цитированную форму '<< 'ENDSSH'' –

+0

Таким образом, он работает на удаленном компьютере, но также переменная' $ CURRENT_LOG' становится удаленной. Как скопировать два удаленных vars обратно на исходный компьютер? – Serge

2

Попробуйте избежать ваших вызовов для CMD-замещением

CURRENT_LOG=`mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $1}'` 

сейчас находится

CURRENT_LOG=\`mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $1}'\` 

или присоединитесь к 90-м ;-) и используйте $(...) fo п.м. CMD замещения (спасся также)

CURRENT_LOG=\$(mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $1}') 

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

IHTH

+0

Пробовал с 1..3 обратными косыми чертами - false. – Serge

+0

Я знаю, что это звучит сумасшедшим (и это было через 2-3 года с тех пор, как я сделал это), но я знаю, что я удивился, что мне пришлось использовать целых 5 '' символов. Это не решит проблему появления значений var в вашей локальной среде. Я думаю, вам придется собирать и анализировать выходные данные с удаленного на локальной стороне. Удачи. – shellter

0
doRemote() { 

ssh localhost <<ENDSSH 
     ls 
     cat /etc/issue 
     VAR1=\$(/home/thumper/bash/test2.sh) 
     echo \$VAR1 >> /home/thumper/bash/test.txt 
ENDSSH 
} 

doRemote 
+0

пытается сделать это без временных файлов. – Serge

2

Итак, у вас есть две совершенно разные проблемы:

  • вы работаете встроенные команды локально, перед вызовом ssh, что вы намеревались работать удаленно, как часть ввод прошел через ssh.
  • Вы назначаете переменные на удаленном хосте, которые вы назначили на локальном хосте.

Другие ответы уже покрыты # 1 (а именно: лучшее экранирование), поэтому я расскажу номер № 2.

# 2 сложно, но один подход состоит в том, чтобы изменить команду ssh на печать операторов присваивания, которые должны выполняться локально. Затем вы можете обернуть его командой eval, которая запускает эти операторы присваивания.

Все сказали, вы в конечном итоге с чем-то вроде этого:.

function doRemote() { 
    eval "$(ssh s1.domain.com <<' ENDSSH' 
     mysql -u root -pXXX --execute="DROP DATABASE db; CREATE DATABASE db;" >&2 
     mysql -u root -pXXX --database=db < $WORKDIR$FILENAME >&2 
     sudo rm -rf /var/log/mysql/db-bin.* >&2 
     mysql -u root -pXXX --execute="FLUSH LOGS;" >&2 
     printf 'CURRENT_LOG=%q\n' `mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $1}'` 
     printf 'CURRENT_POS=%q\n' `mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $2}'` 
     # ... 
    ENDSSH)" 
} 

(Заметьте, что я добавил >&2 всех предыдущих команд, поэтому их вывод идет в стандартный-ошибки вместо стандартного вывода Это потому что стандартный вывод захватывается и eval 'd локально, что явно вам не нужно.)

0

Также возможно сохранить содержимое всего документа здесь в переменной, а затем передать эту переменную в качестве аргумента команда ssh.

Добавление некоторых операторов echo позволяет получить доступ к переменным ${CURRENT_LOG} и ${CURRENT_POS} на локальной машине. Просто убедитесь, что $ssh_output ниже содержит только вывод операторов echo (но также см .: Run a parallel command while waiting for ssh).

Не перенаправляйте stdin из документа здесь, если ssh собирается выполнить sudo с запросом пароля.

# untested 
function doRemote() { 

cmds="$(cat <<'ENDSSH' 
mysql -u root -pXXX --execute="DROP DATABASE db; CREATE DATABASE db;" 
mysql -u root -pXXX --database=db < $WORKDIR$FILENAME 
sudo rm -rf /var/log/mysql/db-bin.* 
mysql -u root -pXXX --execute="FLUSH LOGS;" 
CURRENT_LOG=`mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $1}'` 
echo "export CURRENT_LOG='${CURRENT_LOG}';" 
CURRENT_POS=`mysql -u root -pXXX --execute="SHOW MASTER STATUS" -AN | awk '{print $2}'` 
echo "export CURRENT_POS='${CURRENT_POS}';" 
# ... 
ENDSSH 
)" 

# use ssh -t for sudo command 
ssh_output="$(ssh -t s1.domain.com "$cmds")" 
eval "$ssh_output" 
return 0 

} 
Смежные вопросы