BASH: поддерживать соединение

У меня такой сценарий:

Я использую netcat для подключения к хосту, на котором запущен telnet сервер на порту 23, я вхожу в систему, используя предоставленные имя пользователя и пароль, выполняю несколько команд, после чего мне нужно провести довольно сложный анализ предоставленных выходных данных. Естественно, приходит на ум expect со сценарием вроде этого:

spawn nc host 23
send "user\r"
send "pass\r"
send "command\r"
expect EOF

затем он выполняется с expect example.scr >output.log, так что выходной файл может быть проанализирован. Синтаксический анализатор - это 150+ строк bash кода, который выполняется менее 2 секунд и принимает решение, какую команду следует выполнить следующей. Таким образом, он заменяет «команду» на «команду2» и снова выполняет сценарий expect, например:

sed -i '/send "command\r"/send "command2\r"/' example.scr
expect example.scr >output.log

Очевидно, нет необходимости повторно устанавливать telnet соединение и выполнять процесс входа в систему заново, просто нужно выполнить одну команду telnet после 2 секунд обработки. Можно сделать вывод, что telnet сеанс должен оставаться активным как фоновый процесс, чтобы с ним можно было свободно разговаривать в любой момент времени. Естественно, приходит на ум использование named pipes:

mkfifo in
mkfifo output.log
cat in | nc host 23 >output.log &
echo -e "user\npass\ncommand\n" >in
cat output.log

После записи в файл EOF закрывает named pipe, завершая сеанс telnet. Я думал, какой вечный процесс можно передать по конвейеру netcat, чтобы его можно было использовать как telnet ретранслятор на хост. Мне в голову пришла очень глупая идея, но она работает:

nc -k -l 666 | nc host 23 >output.log &
echo -e "user\npass\ncommand\n" | nc localhost 666
cat output.log

Сервер netcat запускается с k (eep активен), прослушивает порт 666, и любой поток данных перенаправляется клиенту netcat telnet, подключенному к хосту, в то время как весь диалог сбрасывается в output.log. Теперь можно echo отправлять команды telnet на nc localhost 666 и читать результат из output.log.

Следует иметь в виду, что сценарий expect можно легко изменить для поддержки SSH и даже serial console соединения, просто создав ssh или socat вместо netcat. Мне никогда не нравился expect, потому что он вынуждает использовать другой язык сценариев в bash, требует tcl библиотек и должен быть скомпилирован для встроенных платформ, в то время как netcat является частью busybox и легко доступен повсюду.

Итак, вопрос в том, можно ли это сделать проще? Я бы поставил на то, что между консолью и TCP socket будет какая-то связь. Любые предложения приветствуются.


person Ulrik    schedule 08.03.2015    source источник
comment
Переход на Perl или Python устранит ряд сложностей. Для обоих доступны ожидаемые библиотеки.   -  person tripleee    schedule 09.03.2015
comment
... потому что он заставляет использовать другой язык сценариев в bash ..., ... и должен быть скомпилирован для встроенных платформ, в то время как netcat является частью busybox и легко доступен повсюду, поэтому я увидел, что Python должно предложение, но это не удобно для этой конкретной цели   -  person Ulrik    schedule 11.03.2015
comment
expect уже является зависимостью, не так ли? Я считаю, что скрипт Python и его зависимости можно скомпилировать в один blob-объект, хотя я видел это только в Windows с py2exe.   -  person tripleee    schedule 11.03.2015
comment
Кстати, sed -i кажется расточительным и хрупким. Почему бы вам не sed 's/send "command"/send "command2"/' example.scr | expect (при условии, что expect может использовать сценарий на стандартном вводе, и если в вашей команде sed отсутствует начальный s, потому что тот, который у вас есть, не разбирается)?   -  person tripleee    schedule 11.03.2015
comment
expect - это зависимость, которой я бы очень хотел избежать. С другой стороны, sed выполняет замену файла сценария, потому что этот файл по пути сшивается несколькими разными сценариями ...   -  person Ulrik    schedule 11.03.2015
comment
Я бы просто использовал для этого expect, запустил сценарий bash в выходном файле и использовал его вывод в качестве следующей команды для запуска. Нет необходимости изменять исходный файл сценария и т. Д.   -  person Etan Reisner    schedule 15.06.2015


Ответы (1)


Как насчет использования файлового дескриптора?

exec 3<>/dev/tcp/host/port

while true; do
    echo -e "user\npass\ncommand" >&3
    read_response_generate_next_command <&3 >&3
    # if no more commands, break;
done

exec 3>&-
person anishsane    schedule 15.06.2015