1

Я делаю сценарии развертывания для своего проекта, и я делаю функцию, которая должна иметь возможность запускать команды как локально, так и удаленно (на сервере через ssh) и возвращать вывод текста.

При выполнении локальной команды я легко могу узнать, завершила ли команда, ожидая ее PID. Когда я посылаю команду через открытое соединение SSH, я получаю выходные данные обратно, но я не знаю, была ли команда выполнена или команда все еще выполняется и будет генерировать больше выходных данных позже.

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

Похоже, что это может быть распространенной проблемой и может иметь простое решение, возможно, даже что-то, что встроено в SSH, поэтому я спрашиваю здесь: как я могу, через открытое соединение SSH, знать, есть ли команды, которые я отправлено закончено. Если бы я мог как-то собрать код выхода, это было бы здорово.


Чтобы дать более конкретный пример, это в основном демонстрирует мою проблему в Ruby:

io = IO.popen(["ssh", "-q", "my-server"], "r+")

io.write("some command\n")

# Sleep for some arbitrary amount of time, because I don't know when the
# command has finished :(
sleep 1

output = io.readpartial(1_000_000)

io.write("some command\n")

# Sleep for some arbitrary amount of time, because I don't know when the
# command has finished :(
sleep 1

output = io.readpartial(1_000_000)

2 ответа2

2

Оберните вашу команду в скрипт, который уведомит вас, когда это будет сделано.

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

Приведенный ниже пример выполнит your-command , запишет ее вывод и stderr в файл, а затем использует malix для отправки результатов. Конечно, есть гораздо лучший способ убедиться, что файл, который выводится, является уникальным, чем использование псевдопеременной $$ (возможно, используйте процедуру, которая генерирует случайную строку).

#/bin/bash
your-command > /tmp/$$.$0.output 2>&1
RESULT=$?
echo >> /tmp/$$.$0.output
echo "Exit code $RESULT" >> /tmp/$$.$0.output
cat /tmp/$$.$0.output | mailx -s "your-command has finished with exit code $RESULT." you@some-mail-server.invalid
rm /tmp/$$.$0.output

Если вам нужно что-то, что позволяет вам указывать очередь команд, загляните в Task Spooler (apt-get install tsp в Debian), который позволяет вам добавлять и удалять команды из очереди, и я верю, что вы можете даже отправить их по электронной почте.

Читая ваш вопрос более внимательно ... кажется, вы рассматриваете то, что SSH-соединение вводит / выводит как необработанный поток ввода-вывода.

SSH предоставляет зашифрованный канал и имеет некоторые функции для переадресации портов, и не более того. Типичная вещь, связанная с этим каналом - это оболочка, которая обычно ожидает интерактивного пользователя на другом конце.

Я думаю, что одноцелевые ключи могут несколько достичь того, что вы пытаетесь сделать, довольно легко, но проще всего будет создать небольшой скрипт-обертку, который делает это:

#/bin/bash
$@ 
echo "==== Command Output Finished ===="

а затем найдите строку ==== Command Output Finished ==== в своих процедурах ввода-вывода, чтобы определить, где находится граница между выводами команды. Конечно, вы должны выбрать что-то, что не может быть частью действительного вывода для команды. Возможна более сложная схема.

SMTP делает нечто подобное со своими граничными заголовками.

0

Если вы по-прежнему решаете запускать каждую команду в отдельном сеансе SSH, вы можете ускорить время, необходимое для запуска каждого сеанса, с помощью уже открытого соединения. Это означает, что вам нужно заплатить только один раз за подключение, что быстро запускает последующие сеансы.

Самый простой способ установить это, открыв первое соединение с этим:

ssh -M -S /tmp/ssh_mux_%h_%p_%r myserver

Затем откройте каждое последующее соединение с:

ssh -S /tmp/ssh_mux_%h_%p_%r myserver "command"

Более подробная информация находится на странице руководства ssh_config в ControlMaster и ControlPath или онлайн здесь и здесь.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .