Я прочитал здесь несколько сообщений по этой теме, но каждое решение, которое я нахожу, похоже, представляет собой один лайнер, в котором вы запускаете одну команду.
Я создаю сценарий, в котором я использую ssh для нескольких разных хостов один за другим. Цель состоит в том, чтобы подключиться к машине по ssh, выполнить несколько локальных команд, выполнить сценарий, дождаться его завершения, а затем выйти из сеанса ssh и перейти к следующему.
Однако, когда я использую команду «exit», она не работает и просто полностью закрывает сценарий.
Я предполагаю, что ваш скрипт не выходит из сеанса оболочки, потому что вы вызываете его напрямую с помощью ./exit.sh
. Вам следует source
вместо этого.
An exit
оператор в вашем сценарии закроет сеанс оболочки.
$ source exit.sh
# or
$ . exit.sh
В source
builtin выполняет ваш скрипт в текущий контекст оболочки, пока ./exit.sh
запускает новая оболочка запустить его.
Вы пытались поместить команды в файл и использовать с ним cat или EOF?
ssh -t me@server1.com << EOF
command1
command2
exit
EOF
Я бы рекомендовал посмотреть на pssh
для того, что вы пытаетесь выполнить - он позволяет легко справляться с нюансами открытия / закрытия соединений между машинами и даже может работать параллельно, чтобы сократить время выполнения.
Он все еще использует ssh
как транспортный протокол, так что он, очевидно, так же безопасен, как зацикленный ssh
подключение.
Обычно я делаю это для своих узлов.
Предполагая, что ваш список узлов находится в файле / tmp / serverlist:
server001
server002
server003
server004
server005
server006
Предполагая, что я хочу запустить серверы с 001-006:
#!/bin/bash
LINUX_COMMAND='uptime'
for i in `cat /tmp/serverlist`
do
ssh ${i} ${LINUX_COMMAND}
done
Обычно вы можете сделать for
петля с ssh
без проблем.
$ for srv in 192.168.88.138; do echo $srv:; ssh $srv uptime; done
192.168.88.138:
13:27:25 up 30 days, 8:42, 1 user, load average: 4.15, 4.06, 4.06
Итак, в этом случае я побежал uptime
с другой стороны. Вы можете заменить uptime
с чем вы хотите работать. Что бы вы ни положили, там должен быть выход. uptime
завершается после того, как он распечатает свой вывод, но если вы пишете сценарий, вам может потребоваться убедиться, что он в конечном итоге завершится, чтобы for
цикл может продолжаться.
Если вы делаете что-то сложное, я бы рекомендовал создать сценарий в отдельном файле, а затем scp
подключите его к серверу, на котором вы хотите его запустить, затем ssh, чтобы запустить его. Попытка внести что-то сложное в ssh с помощью цитирования и экранирования является более сложной задачей, чем обычно.
Я делал это сотни раз, и это отлично работает, когда вы хотите, чтобы что-то работало на одном сервере за раз. Если вы хотите, чтобы все работало параллельно, есть другие варианты, но я бы посмотрел на анзибль первый.
Итак, это работает, после того как мы опробовали около десятка вещей в Интернете. Мне пришла в голову идея найти мой сеанс ssh в моем сеансе ssh и убить его
В моем сценарии:
ssh ${blah} "/usr/bin/run_some_command ; ps -fu myUsername | grep -i MySSHconnection | grep -v grep | awk '{print \$2}'| xargs -i kill -9 {} "
Вы пытаетесь сделать то же самое со многими хостами параллельно или используете результаты команд, запущенных на одном хосте, чтобы решить, что делать на следующем хосте?
Если вы пытаетесь запускать команды на нескольких хостах параллельно, это то, для чего был создан rsh. В наши дни считается, что rsh имеет очень низкий уровень безопасности, поэтому более актуальным и правильным вариантом для этого будет pdsh. Вы бы переписали свой сценарий оболочки так, чтобы он выполнялся на одном хосте, а затем использовали бы pdsh для выполнения этого скрипта на многих хостах.