Bash tcp redirection end of transmission

Я сделал простую сетевую услугу с xinetd, которая считывает строку из tcp-сокета и выводит ее кодированный вид. Оригинальный двоичный код (qrencode), просто считывающий stdin.

Он отлично работает, когда я использую его с netcat как echo string | nc <ip> <port> echo string | nc <ip> <port>

Но он не отвечает, когда я пытаюсь использовать его с помощью перенаправления bash tcp.

 exec 7<>/dev/tcp/<ip>/<port> echo string >&7 cat <&7 

Он ждет вечно. Я попробовал повторить \ 004, cat / dev / null для этого fd и не повезло. Как я могу заставить его работать?

2 Solutions collect form web for “Bash tcp redirection end of transmission”

Эта служба inetd или ваш, вероятно, ждут EOF перед выходом (и затем закрытием соединения).

Для этого вам понадобится клиент для выключения отправляющей стороны сокета при сохранении открытой стороны приема. Это то, что делает nc , когда он обнаруживает EOF на своем stdin.

Виртуальный интерфейс /dev/tcp/host/port bash (скопирован из ksh) не позволяет этого. Даже более гибкая альтернатива zsh не имеет возможности асимметрично отключать соединения.

Вместо этого вы можете рассчитывать на таймаут, но это было бы ненадежным. Лучше всего полагаться на специальные утилиты, такие как nc или socat (возможно, с coproc, чтобы иметь аналогичный интерфейс), или использовать язык программирования с надлежащим сетевым API (с интерфейсом для shutdown() ).

Символ 0x04 ( ^D ) означает только EOF для терминальных устройств, когда линейная дисциплина находится в режиме icanon (реализует строчный редактор строк). Поэтому для этого вам придется вставить псевдотерминал между сокетом, созданным xinetd и вашим сервисом. Например, запустив его с помощью:

 socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3 

вместо

 your-service 

Затем вам нужно отправить:

 printf 'text\n\4' >&7 

Или:

 printf 'text\4\4' >&7 

для вашего обслуживания, чтобы увидеть конец ввода.

Из-за этого редактора строк your-service будет видеть только вход, когда вы отправляете символы новой строки или ^D (мы отключили все другие редактирующие символы, такие как werase , werase , kill above и обработка ^C , ^Z … также отключены как часть raw ).

Таким образом, вы можете вставить вместо этого входной препроцессор, который завершает работу с этим символом 0x4:

 awk -v RS='\4' -v ORS= '{print; exit}' | your-service 

(обратите внимание, что этот awk не может быть mawk поскольку mawk настаивает на том, чтобы не обрабатывать его ввод, если он не получил полный буфер или eof).

Похоже, что если ваша служба не закрывает установленный сеанс TCP, нет другого пути, кроме остановки клиентской стороны соединения. Например, используя команду timeout:

 timeout 1 cat <&7 

Кроме того, другие команды ( echoing \004, cat /dev/null ), которые вы пытаетесь, скорее всего, терпят неудачу, потому что вы выполняете их из другой оболочки. Обратите внимание, что дескриптор файла 7 прикреплен к оболочке, где вы выполнили первый exec 7<>/dev/tcp/<ip>/<port> , и поэтому вы можете взаимодействовать с ним только из первой оболочки.

Справка

  • Xinetd: завершение соединения с серверным скриптом
  • Если я перезапущу службу xinetd, это влияет на текущие активные FTP-соединения?
  • Настройка xinetd для OpenSuSE
  • Какие службы принимают tcp-соединение?
  • Не удается заставить TFTP-сервер работать с Ubuntu с помощью xinetd
  • Настройка nice и ionice для rsync через xinetd
  • Является ли xinetd еще лучшим методом, позволяющим нон-корневым демонам прослушивать привилегированные порты?
  • Как запустить демон talkd?
  • Telnet не выводит эхо из сценария xinetd
  • Запуск FTP с помощью xinetd
  • TFTP не прослушивает определенный порт при запуске с использованием правила xinetd
  • Linux и Unix - лучшая ОС в мире.