Назад | Перейти на главную страницу

Как выйти из SSH-соединения в сценарии bash

Я прочитал здесь несколько сообщений по этой теме, но каждое решение, которое я нахожу, похоже, представляет собой один лайнер, в котором вы запускаете одну команду.

Я создаю сценарий, в котором я использую 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 подключение.

https://linux.die.net/man/1/pssh

Обычно я делаю это для своих узлов.

Предполагая, что ваш список узлов находится в файле / 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 для выполнения этого скрипта на многих хостах.