Come grep output di netcat


13

Sto provando a visualizzare in streaming streaming di testo dal vivo netcat, ma per me non funziona:

netcat localhost 9090 | grep sender

non restituisce nulla, ma sono sicuro che dovrebbe.

Se reindirizzo l' netcatoutput su un file e aggiungo alcuni ritardi (simula l'ambiente reale), allora funziona:

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

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

Ho anche provato ad aggiungere --line-bufferedma senza successo.

Cosa faccio di sbagliato?

Modificare:

Ho notato lo stesso problema con sed, l'output è vuoto.

Ma, per esempio, hexdumpconverte il testo in esadecimale dal 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|

2
Forse viene bufferizzato nella pipe? Potresti provare a usare stdbuf -o0 netcat localhost 9090 | grep sender(preso da qui )
user43791

Funziona così? netcat -z localhost 9090 | grep sender
Gilles Quenot,

@ user43791 l'output è ancora vuoto, ma sono sicuro che netcat ha restituito la stringa corrispondente
tomekceszke il

@sputnick questo torna immediatamente alla shell e non aspetta un evento
tomekceszke,

1
Non ci sono nuove linee nel hexdump, quindi grepprobabilmente sta aspettando all'infinito una nuova riga. catfunziona poiché grepotterrà un EOF se non una newline, almeno. Forse provare awkcon {come RS?
Muru,

Risposte:


4

È possibile utilizzare il readcomando ( bashincorporato) per forzare la lettura dei caratteri uno per 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

Questo script dovrebbe stampare ogni output completo con bilanciamento {e }, ma è possibile modificarlo per fare quello che vuoi. Questo script NON farebbe bene su un benchmark rispetto a praticamente nulla, ma è piuttosto semplice e sembra funzionare per me ...

Nota che il tuo campione di test non aveva corrispondenza {e }, quindi se questo è il caso dell'input reale, potresti voler cambiare i criteri per stampare la linea.


Sembra che le parentesi graffe non corrispondenti siano solo perché ha pubblicato solo l'inizio dell'output.
Barmar,

8

La risposta è qui: grep non corrisponde nell'output nc

netcat restituisce log dettagliati con errori standard, quindi è necessario acquisire errori prima di eseguire il pipe su grep.

$ netcat -zv localhost 1-9000 2>&1 | grep succeeded

Questa risposta mi ha appena reso la soluzione. È stato molto strano quando ho eseguito quel comando senza 2>&1, sembra che grep non abbia funzionato affatto.
Marecky,

2

Penso che il problema sia l'assenza di nuove righe netcatnell'output. Riesco a vedere due soluzioni alternative:

  1. Inserisci una nuova riga ogni xsecondo (con conseguenze sfavorevoli se la nuova riga viene inserita nel mezzo di source):

    ( while sleep 1; do echo; done & netcat ... ) | grep source
    
  2. Utilizzare awkcon un RS diverso da Newline:

    netcat ... | awk -v RS='}' -v ORS='}' '/source/'
    

Uscita ancora vuota. Per essere sicuro che il comando sia corretto, corro su un flusso scaricato - cat netcat_output | awk -v RS='}' -v ORS='}' '/sender/'L'output era ok:,"sender":"xbmc"}
tomekceszke,

Ho appena verificato la prima soluzione e funziona ! Ma come hai detto, può dividere l'output in modo che non possa essere la soluzione finale. Comunque molte grazie!
tomekceszke,

1

Aggiungi --line-bufferedper utilizzare il buffering di linea sull'output:

netcat localhost 9090 | grep --line-buffered sender 

L'ho già provato, non ha funzionato.
tomekceszke,

1

usa il watchcomando:

watch 'netcat localhost 9090 | grep sender'

Non funziona troppo. Lo stesso con sed ... Ma, per esempio, questo: netcat localhost 9090 | hexdump funziona e sostituisce il testo in hex live, perché?
tomekceszke,


0

In Bash puoi usare i file pseudo-dispositivo per aprire una connessione TCP e grep come al solito. Per esempio:

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

Per testarlo, esegui semplicemente un server che può inviare alcuni file, come:

$ nc -vl 1234 < /etc/hosts

Quindi, in un altro terminale, eseguire il test grepsull'output:

$ grep "127" < /dev/tcp/localhost/1234
127.0.0.1   localhost
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.