GNU/Linux >> Tutoriales Linux >  >> Linux

Bash Tcp Redirección ¿Fin de la transmisión?

Hice un servicio de red simple con xinetd que lee una cadena del socket tcp y genera su vista codificada. Binario original (qrencode) solo leyendo stdin.

Funciona bien cuando lo uso con netcat como echo string | nc <ip> <port>

Pero no responde cuando trato de usarlo a través de la redirección bash tcp.

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

Espera para siempre. Intenté repetir \004, cat /dev/null en este fd y no tuve suerte.
¿Cómo puedo hacer que funcione?

Respuesta aceptada:

Ese inetd El servicio o el suyo probablemente esté esperando EOF antes de salir (y luego cerrar la conexión).

Para hacer eso, necesitaría que el cliente apague el lado de envío del socket mientras mantiene abierto el lado de recepción. Eso es lo que nc hace cuando detecta EOF en su stdin.

El /dev/tcp/host/port interfaz virtual de bash (copiado de ksh) no permite eso. Incluso zsh 's ztcp alternativa más flexible no tiene la capacidad de cerrar conexiones asimétricamente.

En su lugar, podría confiar en un tiempo de espera, pero eso no sería confiable. Así que es mejor seguir confiando en utilidades dedicadas como nc o socat (posiblemente con un coproc para tener una interfaz similar), o use un lenguaje de programación con una API de red adecuada (con una interfaz para shutdown() ).

El carácter 0x04 (^D ) solo significa EOF para dispositivos terminales cuando la disciplina de línea está en icanon modo (implementa un editor de línea crudo). Así que para que funcione tendrías que insertar un pseudo-terminal entre el socket creado por xinetd y su servicio. Por ejemplo, comenzando con:

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

en lugar de

your-service

Entonces tendrías que enviar:

printf 'text\n\4' >&7

O:

printf 'text\4\4' >&7

para que su servicio vea el final de la entrada.

Debido a ese editor de líneas, your-service solo verá la entrada cuando envíe una nueva línea o ^D caracteres (hemos deshabilitado todos los demás caracteres de edición como werase , erase , kill arriba y el ^C , ^Z … el manejo también está deshabilitado como parte de raw ).

Por lo tanto, también podría insertar un preprocesador de entrada que se cierre con ese carácter 0x4 como:

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

(tenga en cuenta que eso awk no puede ser mawk como mawk insiste en no procesar su entrada mientras no reciba un búfer completo o eof).

Relacionado:¿convertir tabla a archivo ini usando matrices bash?
Linux
  1. ¿Cómo agregar nuevas líneas en variables en Bash Script?

  2. ¿Cómo establecer parámetros cuando Pipe Bash Script to Bash?

  3. Arreglar la secuencia de comandos de Bash que espera la entrada de la ruta con / Al final se rompe cuando la ruta no termina con /?

  4. The Point Of The Bash Null-operator “:”, Colon?

  5. Bash script para eliminar todos los archivos excepto N cuando se ordenan alfabéticamente

Use este útil script de Bash cuando observe las estrellas

Bash Shebang

Redirección de Bash explicada con ejemplos

Encerrando vs. ¿No encerrar el valor de una variable entre comillas en Bash?

¿Cómo guardar + cerrar archivo al editar en bash?

Comportamiento extraño del historial de bash cuando se ejecutan varias sesiones