Cómo grep salida de netcat

13

Estoy tratando de obtener una secuencia de texto en vivo netcat, pero no funciona para mí:

netcat localhost 9090 | grep sender

no devuelve nada, pero estoy seguro de que debería.

Si redirijo la netcatsalida a un archivo y agrego algunos retrasos (simular el entorno real), entonces funciona:

$ (sleep 5; cat netcat_output; sleep 5) | grep sender

{"jsonrpc":"2.0","method":"GUI.OnScreensaverDeactivated","params":{"data": "shuttingdown":false},"sender":"xbmc"}}

También intenté agregar --line-bufferedpero sin éxito.

¿Qué hice mal?

Editar:

Noté el mismo problema con sed, la salida está vacía.

Pero, por ejemplo, hexdumpconvierte el texto en hexadecimal en vivo:

$ netcat localhost 9090 | hexdump -C
00000000  7b 22 6a 73 6f 6e 72 70  63 22 3a 22 32 2e 30 22  |{"jsonrpc":"2.0"|
00000010  2c 22 6d 65 74 68 6f 64  22 3a 22 50 6c 61 79 65  |,"method":"Playe|
00000020  72 2e 4f 6e 50 6c 61 79  22 2c 22 70 61 72 61 6d  |r.OnPlay","param|
00000030  73 22 3a 7b 22 64 61 74  61 22 3a 7b 22 69 74 65  |s":{"data":{"ite|
00000040  6d 22 3a 7b 22 69 64 22  3a 36 2c 22 74 79 70 65  |m":{"id":6,"type|
00000050  22 3a 22 6d 6f 76 69 65  22 7d 2c 22 70 6c 61 79  |":"movie"},"play|
00000060  65 72 22 3a 7b 22 70 6c  61 79 65 72 69 64 22 3a  |er":{"playerid":|
00000070  31 2c 22 73 70 65 65 64  22 3a 31 7d 7d 2c 22 73  |1,"speed":1}},"s|
tomekceszke
fuente
2
Tal vez se amortigua en la tubería? Puede intentar usar stdbuf -o0 netcat localhost 9090 | grep sender(tomado de aquí )
user43791
¿Funciona así? netcat -z localhost 9090 | grep sender
Gilles Quenot
@ user43791 la salida todavía está vacía, pero estoy seguro de que netcat devolvió la cadena coincidente
tomekceszke
@sputnick este vuelve inmediatamente al shell y no espera un evento
tomekceszke
1
No hay nuevas líneas en el hexdump, por greplo que probablemente esté esperando sin cesar una nueva línea. catfunciona ya grepque obtendrá un EOF si no una nueva línea, al menos. ¿Quizás probar awkcon {RS?
muru

Respuestas:

4

Puede usar el readcomando ( bashincorporado) para forzar la lectura de los caracteres uno por uno:

netcat localhost 9090 | (
    cnt=0
    line=
    while read -N 1 c; do
        line="$line$c"
        if [ "$c" = "{" ]; then
            cnt=$((cnt+1))
        elif [ "$c" = "}" ]; then
            cnt=$((cnt-1))
            if [ $cnt -eq 0 ]; then
                printf "%s\n" "$line"
                line=
            fi
        fi
    done
) | grep sender

Este script debe imprimir cada salida completa con balanceo {y }, pero puede cambiar el script para hacer lo que quiera. Este script NO funcionaría bien en un punto de referencia en comparación con casi cualquier cosa, pero es bastante simple y parece funcionar para mí ...

Tenga en cuenta que su muestra de prueba no tenía coincidencia {y }, por lo tanto, si este es el caso de la entrada real, es posible que desee cambiar los criterios para imprimir la línea.

user43791
fuente
Parece que las llaves que no coinciden es solo porque solo publicó el comienzo de la salida.
Barmar
8

La respuesta está aquí: grep no coincide en la salida nc

netcat genera registros detallados de error estándar, por lo que debemos capturar los errores antes de canalizar a grep.

$ netcat -zv localhost 1-9000 2>&1 | grep succeeded
tkdave
fuente
Esta respuesta me hizo la solución. Eso fue muy extraño cuando ejecuté ese comando sin 2>&1, parece que grep no funcionó en absoluto.
Marecky el
2

Creo que el problema es la ausencia de nuevas líneas en el netcatresultado. Puedo ver dos soluciones:

  1. Inserte una nueva línea cada xsegundo (con consecuencias desafortunadas si la nueva línea se inserta en el medio de source):

    ( while sleep 1; do echo; done & netcat ... ) | grep source
    
  2. Usar awkcon un RS que no sea nueva línea:

    netcat ... | awk -v RS='}' -v ORS='}' '/source/'
    
muru
fuente
Aún salida vacía. Para asegurarme de que el comando es correcto, ejecuto el flujo volcado - cat netcat_output | awk -v RS='}' -v ORS='}' '/sender/'La salida estuvo bien:,"sender":"xbmc"}
tomekceszke
¡Acabo de comprobar la primera solución y funciona ! Pero como mencionó, puede dividir la salida, por lo que no puede ser la solución final. De todos modos muchas gracias!
tomekceszke
1

Agregar --line-bufferedpara usar el buffering de línea en la salida:

netcat localhost 9090 | grep --line-buffered sender 
Ciro
fuente
Ya probé esto, no funcionó.
tomekceszke
1

watchcomando de uso :

watch 'netcat localhost 9090 | grep sender'
αғsнιη
fuente
Tampoco funciona Lo mismo con sed ... Pero, por ejemplo, esto: netcat localhost 9090 | hexdump funciona y reemplaza texto a hexadecimal en vivo, ¿por qué?
tomekceszke
0

En Bash puede usar archivos de pseudodispositivos para abrir una conexión TCP y grep como de costumbre. Por ejemplo:

$ grep "sender" < /dev/tcp/example.com/1234

Para probarlo, simplemente ejecute el servidor que puede enviar algún archivo, como:

$ nc -vl 1234 < /etc/hosts

Luego, en otro terminal, ejecute la prueba a grepla salida:

$ grep "127" < /dev/tcp/localhost/1234
127.0.0.1   localhost
kenorb
fuente