Como grep saída netcat

13

Estou tentando grep ao vivo netcat, mas não funciona para mim:

netcat localhost 9090 | grep sender

não retorna nada, mas tenho certeza de que deveria.

Se eu redirecionar a netcatsaída para um arquivo e adicionar alguns atrasos (simular o ambiente real) - funcionará:

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

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

Eu também tentei adicionar, --line-bufferedmas sem sucesso.

O que eu faço de errado?

Editar:

Percebi o mesmo problema com sed, a saída está vazia.

Mas, por exemplo, hexdumpconverte texto em hexadecimal:

$ 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
fonte
2
Talvez fique amortecido no cano? Você pode tentar usar stdbuf -o0 netcat localhost 9090 | grep sender(extraído daqui )
user43791
Funciona assim? netcat -z localhost 9090 | grep sender
Gilles Quenot
@ user43791 a saída ainda está vazio, mas eu tenho certeza que netcat retornou seqüência de correspondência
tomekceszke
@sputnick este retorna imediatamente para descascar e não esperar por um evento
tomekceszke
1
Não há novas linhas no hexdump, portanto, grepprovavelmente está esperando infinitamente por uma nova linha. catfunciona, pois grepreceberá um EOF, se não uma nova linha, pelo menos. Talvez tente awkcom {como RS?
Muru

Respostas:

4

Você pode usar o readcomando ( bashinterno) para forçar os caracteres a serem lidos um por um:

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

Esse script deve imprimir todas as saídas completas com balancing {e }, mas você pode alterar o script para fazer o que quiser. Esse script NÃO funcionaria bem em uma referência comparada a praticamente qualquer coisa, mas é bem simples e parece funcionar para mim ...

Observe que sua amostra de teste não possui correspondência {e }, portanto, se este for o caso da entrada real, convém alterar os critérios para imprimir a linha.

user43791
fonte
Parece que o aparelho incompatível é apenas porque ele postou apenas o início da saída.
Barmar 31/12/14
8

A resposta está aqui: grep não corresponde na saída nc

O netcat gera logs detalhados para erro padrão, portanto, precisamos capturar erros antes de enviar para grep.

$ netcat -zv localhost 1-9000 2>&1 | grep succeeded
tkdave
fonte
Esta resposta me fez solução. Isso foi muito estranho quando executo esse comando sem 2>&1, parece que o grep não funcionou.
Marecky
2

Eu acho que a questão é a ausência de novas linhas na netcatsaída. Eu posso ver duas soluções alternativas:

  1. Insira uma nova linha a cada xsegundo (com conseqüências infelizes se a nova linha for inserida no meio de source):

    ( while sleep 1; do echo; done & netcat ... ) | grep source
    
  2. Use awkcom um RS diferente da nova linha:

    netcat ... | awk -v RS='}' -v ORS='}' '/source/'
    
muru
fonte
Saída ainda vazia. Para garantir que o comando esteja correto, eu corro no fluxo despejado - cat netcat_output | awk -v RS='}' -v ORS='}' '/sender/'A saída foi boa:,"sender":"xbmc"}
tomekceszke
Acabei de verificar a primeira solução alternativa e funciona ! Mas, como você mencionou, ele pode dividir a saída e não pode ser a solução final. De qualquer forma, muito obrigado!
2141414
1

Adicione --line-bufferedpara usar o buffer de linha na saída:

netcat localhost 9090 | grep --line-buffered sender 
Cyrus
fonte
Eu já tentei isso, não funcionou.
30614 Deco
1

use o watchcomando:

watch 'netcat localhost 9090 | grep sender'
αғsнιη
fonte
Também não funciona. O mesmo com o sed ... Mas, por exemplo, este: netcat localhost 9090 | O hexdump funciona e substitui o texto pelo hex live, por que?
tomekceszke
0

No Bash, você pode usar arquivos de pseudo-dispositivo para abrir uma conexão TCP e cumpri-la normalmente. Por exemplo:

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

Para testá-lo, basta executar o servidor que pode enviar algum arquivo, como:

$ nc -vl 1234 < /etc/hosts

Em outro terminal, execute o teste grepna saída:

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