Как я могу создать постоянное соединение SSH для потоковых команд в течение определенного периода времени?

9

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

Например, каждый раз, когда что-то происходит на # 1, я хочу запустить задачу на # 2. В этой настройке я должен создать соединение SSH для каждой команды.

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

Якуб Арнольд
источник

Ответы:

12

Не уверен, что это можно использовать в производстве, но вы можете сделать что-то вроде этого:

создать файл на # 1

1> touch /tmp/commands

Затем выполните команду:

1> tail -f /tmp/commands | ssh username@x.x.x.x

Это откроет файл / tmp / команды и начнет отправлять его содержимое на сервер xxxx (# 2) и будет запускать его там построчно

теперь каждый раз, когда что-то случается на # 1, делайте:

1> echo "ls -l" >> /tmp/commands

или

1> echo "reboot" >> /tmp/commands

все, что вы добавите в файл / tmp / команды, будет отправлено на # 2 и выполнено. Просто убедитесь, что вы не запускаете ничего интерактивного или как-то с этим справляетесь.

Виталий Николаев
источник
Это именно то, что я искал, очень креативное решение :)
Якуб Арнольд
5
Я бы добавил, что вы должны использовать tail -F, который обнаружит, что файл был заменен, поэтому, когда он станет гигантским, вы можете стереть его и начать заново с новым файлом.
DerfK
3
@DerfK, альтернативно, mkfifo /tmp/commandsдолжно быть лучшим решением
solotim
18

Автоматическая устойчивость с использованием OpenSSH

Вы также можете использовать ControlMasterфункцию OpenSSH, которая открывает сокет домена unix для первого соединения и повторно использует это соединение во всех последующих вызовах.

Чтобы включить эту функцию, вы можете либо использовать ее -Mв качестве переключателя командной строки, либо включить эту ControlMasterопцию ~/.ssh/ssh_config, например:

ControlMaster auto

Кроме того, вы должны установить ControlPathследующие строки ~/.ssh/ssh_config:

Host *
   ControlPath ~/.ssh/master-%r@%h:%p

Чтобы поддерживать постоянное соединение с хостом, например, если вы хотите запустить скрипт, который должен установить множество соединений ssh ​​с хостом, ни одно из которых не является постоянным в течение всего времени существования скрипта, вы можете заранее запустить автоматическое соединение, используя:

ssh -MNf remotehost

Привет, Несоно

nesono
источник
Я вошел в серверную ошибку, чтобы проголосовать +1 за ваш ответ. Ваш работал!
Карма
ssh -Nзапускает сеанс без удаленной команды, кажется, нет соответствующих параметров в ssh_config.
Jokester
2

В /etc/ssh/ssh_configдобавлении

# Send keep alive signal to remote sshd
ServerAliveInterval 60
Sandra
источник
2

Если вы часто сталкиваетесь с подобными вещами, попробуйте Parallel . Он похож на dsh (распределенная оболочка), но имеет некоторые полезные функции, такие как подсчет семафоров, и он активно поддерживается.

Из документации:

ПРИМЕР: GNU Parallel как система очередей / менеджер пакетов

GNU Parallel может работать как простая система очередей заданий или как менеджер пакетов. Идея состоит в том, чтобы поместить задания в файл и постоянно читать из него GNU Parallel. Поскольку GNU Parallel остановится в конце файла, мы используем tail для продолжения чтения:

echo >jobqueue; tail -f jobqueue | parallel

Чтобы отправить свои работы в очередь:

echo my_command my_arg >> jobqueue

Конечно, вы можете использовать -S для распределения заданий на удаленные компьютеры:

echo >jobqueue; tail -f jobqueue | parallel -S ..

Есть много замечательных примеров, которые просто царапают поверхность. Вот крутой.

ПРИМЕР: Распределение работы на локальные и удаленные компьютеры

Преобразуйте * .mp3 в * .ogg, запустив один процесс на ядро ​​ЦП на локальном компьютере и сервере2:

  parallel --trc {.}.ogg -j+0 -S server2,: \
  'mpg321 -w - {} | oggenc -q0 - -o {.}.ogg' ::: *.mp3
Аллен
источник
0

да можно с трубкой

echo 'echo "hi"' | ssh -i my_private_key tester@host2

это выполнит команду echo "hi" на host2

вам просто нужно написать программу, которая просто выдает команды (не забывайте;) и затем направляет вывод в ssh

JMW
источник
0

Возможно, вы захотите использовать такую ​​программу, как dsh (Distributed SHell), которая предназначена именно для этого :). После настройки ее с именами хостов и настройки аутентификации publickeya вы можете использовать ее для запуска команд на нескольких компьютерах либо последовательно ("run на машине a, затем запустите на машине b ") или в pararell (" запустите на всех машинах одновременно "). Или просто сделайте сценарий

#!/bin/sh
ssh machine -- $@
exec $@
XANi
источник
0

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не могу проверить это сейчас, так как я на Windows-машине с bash, но без ssh.

В скрипте bash вы можете сделать что-то вроде этого:

exec 4> >(ssh --ssh-options-here user@host)

А затем для отправки команд запишите их в FD 4.

echo 'echo hi' >&4

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

user253751
источник