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

использование именованных каналов для управления удаленным сеансом ssh в BASH

Мой вопрос в основном основан на этом https://stackoverflow.com/questions/22479631/pipe-timely-commands-to-ssh?rq=1

Я следую приведенному выше вопросу, и я могу подключиться к серверу, например:

mkfifo CMDs.txt
exec 7> CMDs.txt

затем с другого терминала я подключаюсь к серверу следующим образом:

sshpass -p 'mypass' ssh -tt myuser@${IP} < CMDs.txt 

сеанс устанавливается, но это не интерактивный сеанс (как и должно быть). Но я могу отправлять команды на удаленный сервер, перенаправляя их на файловый дескриптор 7, например:

echo "some command" >&7 
echo "some more command" >&7 

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

sshpass -p 'mypass' ssh -tt myuser@${IP} < CMDs.txt >>outfile.txt

также, как указано в справочном вопросе, exec 7>&- должен завершить сеанс, но этого не произошло, так как же завершить сеанс после того, как я отправлю все свои команды?

Это было забавно (и невероятно полезно!). В области перенаправления ввода / вывода существует большая гибкость и, следовательно, несколько вариантов, но вот что сработало для меня.

Во-первых, действительно, используйте ssh-keygen для создания пары закрытого / открытого ключей и установите открытый ключ на удаленном сервере authorized_keys в файле (это тривиально, повышает безопасность, и для этого существует множество онлайн-руководств). Для дополнительного кредита защитите его паролем и используйте ssh-agent & ssh-add - вам действительно нужно запустить ssh-agent & ssh-add только один раз при загрузке, и после этого все готово.

Несмотря на это, я использую дескриптор файла 7, как и вы, и основываю свои имена FIFO на 7, поэтому я легко запомню, на какой FD мне нужно перенаправить. ;)

# fd=7
# server=[whatever_your_server_name_is]
# mkfifo $server.$fd.in $server.$fd.out
# [ssh-agent if needed]
# ssh -tt $server <$server.$fd.in >$server.$fd.out &
# exec 7>$server.$fd.in

Теперь все готово. Я мог бы прикрепить какой-нибудь сценарий / процесс к $ server. $ Fd.out, но в следующем примере я просто использую cat в качестве слушателя - для лучшей читаемости я выделил это в отдельный сеанс ssh, но это не так. t строго необходимо при использовании символа '&' для фона:

# cat $server.$fd.out

Затем любые произвольные команды, которые вы хотите:

# echo "hostname" >&7
# echo "date" >&7
# echo -e '\003' >&7  # ctrl+c...you're welcome ;)

Вы увидите результат. Обратите внимание: во-первых, вы получите исходный логин motd / banner / etc, поэтому любой скрипт / приложение, которое вы прикрепили к выходному FIFO, должны будут справиться с этим.

Стоит отметить, что весьма вероятно, что один FIFO может использоваться как для чтения, так и для записи, но x.input / output работал лучше для моих личных целей, поэтому я показываю это здесь.

К вашему сведению: Большое спасибо за то, что «доставили меня туда». Я пытался выяснить, как иметь "быстрый" ssh RPC, в котором я устанавливаю длительный сеанс ssh, а затем могу запускать произвольные команды без накладных расходов на аутентификацию ssh для каждой команды - я всегда объединяю их как как можно больше команд, чтобы уменьшить накладные расходы (даже отправка небольших скриптлетов для чтения вывода и выдачи соответствующих последующих команд), но суть в том, что, когда вы хотите выполнить быструю команду, для ssh всегда потребуется несколько секунд для подключения и аутентифицировать (используя ключи, конечно;)), и эти секунды могут быть болезненными, когда вы хотите быстро получить что-то с нескольких устройств. Некоторая элементарная логика для обработки ssh или хоста, уходящего на обед, и автоматического восстановления, и у меня есть довольно приличная настройка для управления моей инфраструктурой.

Выводы из вашего вопроса фактически заполнили недостающие пробелы я нужно было построить то, что мне нужно. Надеюсь, этот ответ тоже помог вам! :)