баш:параллельное выполнение команд через ssh [закрыто]
-
21-12-2019 - |
Вопрос
моя проблема заключается в следующем:Я пишу скрипт, целью которого является параллельный запуск определенных скриптов на разных серверах.То есть я хочу зайти на удаленный сервер, ввести пароль (это не подлежит обсуждению, потому что босс), запустить скрипт, закрыть соединение, пока скрипт еще работает, подключиться к следующему серверу и проделать весь танец заново.Как мне это сделать?
Решение
Предполагая, что 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
}
.