Использование именованных каналов для управления удаленным 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
это прекрасно работает и показывает вывод в другом терминале, на котором я инициировал сеанс. Моя цель - отправлять команды и записывать выходные данные каждой команды в переменную, чтобы я мог проанализировать ее перед отправкой другой команды. Я думаю, что это может быть возможно, читая стандартный вывод, но я не могу понять это, поэтому отправляю вопрос. Я могу захватить вывод в файл, перенаправив его в файл, как это:
sshpass -p 'mypass' ssh -tt myuser@${IP} < CMDs.txt >>outfile.txt
также, как упоминалось в справочном вопросе, exec 7>&-
следует прервать сеанс, но это не так, как завершить сеанс после отправки всех моих команд?
0 ответов
Это было забавно (и невероятно полезно!). В области перенаправления ввода / вывода существует большая гибкость и, следовательно, несколько вариантов, но вот что сработало для меня.
Во-первых, действительно, используйте 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 или хоста, уходящего на обед, и автоматического восстановления, и яУ меня довольно приличная установка для управления моей инфраструктурой.
Выводы из вашего вопроса фактически заполнили недостающие пробелы, которые мне нужны, чтобы построить то, что мне нужно. Надеюсь, этот ответ тоже помог вам!:)