баш:параллельное выполнение команд через ssh [закрыто]

StackOverflow https://stackoverflow.com//questions/21022584

Вопрос

моя проблема заключается в следующем:Я пишу скрипт, целью которого является параллельный запуск определенных скриптов на разных серверах.То есть я хочу зайти на удаленный сервер, ввести пароль (это не подлежит обсуждению, потому что босс), запустить скрипт, закрыть соединение, пока скрипт еще работает, подключиться к следующему серверу и проделать весь танец заново.Как мне это сделать?

Это было полезно?

Решение

Предполагая, что bash является целевой оболочкой на всех удаленных машинах, вы можете сделать для одной машины:

ssh user@host /path/to/script '&>/dev/null' '</dev/null' '&' disown

Для нескольких машин вы можете написать такой сценарий:

hosts='user1@host1 user2@host2'

for host in $hosts
do
  ssh $host /path/to/script '&>/dev/null' '</dev/null' '&' disown
done

Вам нужно просто вводить пароли.

В качестве альтернативы, если вы можете использовать один и тот же пароль для нескольких компьютеров, я бы рекомендовал заглянуть в КластерSSH.Благодаря этому вы можете войти на несколько компьютеров одновременно и вводить команды для отправки всем из них в одном окне или индивидуально в каждом окне xterm.Это избавит вас от многократного ввода одного и того же пароля.После входа в систему вы можете запустить команду, как указано выше (без ssh user@host часть) и выйдите.

Обновлять

Здесь есть пара дополнительных мыслей.Во-первых, вероятно, не стоит полностью отказываться от вывода сценария, поскольку вы никогда не узнаете, что произойдет, если что-то пойдет не так.Вы можете просто поместить его в файл, чтобы просмотреть позже, заменив '&>/dev/null' с '&>filename'.Другой подход — отправить его вам по электронной почте с удаленного компьютера (при условии, что он правильно настроен для этого):

host=user@host
ssh $host \(/path/to/script '2>&1' \| mail -s "$host output" me@me.com\) \
  '&>/dev/null' '</dev/null' '&' disown

Во-вторых, если скрипт находится на локальном хосте, вы можете скопировать его и выполнить одной командой.Предполагается, что это сценарий оболочки, если не просто заменить sh с правильным переводчиком)

</path/to/script ssh user@host \
  cat \>script \; sh ./script '&>/dev/null' '</dev/null' '&' disown

Другие советы

После входа в систему вы можете использовать утилиту экрана для начала нового сеанса терминала, а затем отсоединить из него, пример:

[user@local]$ ssh machine
[user@machine]$ screen -S my_session
# you are now switched to new terminal session named "my_session"
# now you can start long operation, that you want to keep in background
[user@machine]$ yes
# press "Ctrl-a d" to detach, you will go back to original session
[detached from 11271.my_session]
# now you can leave ssh (your session with "yes" running will be kept in background)
# to list existing screen sessions run:
[user@machine]$ screen -list
There is a screen on:
11271.my_session    (Detached)
1 Socket in /var/run/screen/S-user.
# to re-attach use -r
[user@machine]$ screen -r my_session
# you will be back to session with "yes" still running (press Ctrl-C to stop it)
.

Как только вы поймете, как работает экран, вы можете попробовать скрипты;Вот как вы начинаете сеанс экрана в отдельном состоянии, работающий My_Command:

$ screen -d -m my_command
.

expect может автоматизировать это довольно легко:

#!/usr/bin/expect -f

set hosts {your list of hosts goes here ...}
foreach host $hosts {
    spawn ssh -t user@$host screen ./script.sh
    expect "assword:"
    send -- "secret\r"
    sleep 1
    send -- "d"
    expect eof
}
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top