如何grep netcat输出


13

我正在尝试grep的实时文本流netcat,但是对我来说不起作用:

netcat localhost 9090 | grep sender

什么也不会返回,但是我确定应该会返回。

如果我将netcat输出重定向到文件并添加一些延迟(模拟真实环境),则它可以工作:

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

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

我也尝试添加--line-buffered但没有成功。

我做错了什么?

编辑:

我注意到与相同的问题sed,输出为空。

但是,例如,hexdump将文本实时转换为十六进制:

$ 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
也许它在管道中被缓冲了?您可以尝试使用stdbuf -o0 netcat localhost 9090 | grep sender(取自此处
user43791

这样工作吗?netcat -z localhost 9090 | grep sender
Gilles Quenot 2014年

@ user43791输出仍然为空,但是我确定netcat返回了匹配的字符串
tomekceszke 2014年

@sputnick,此人立即返回外壳,不等待事件发生
tomekceszke 2014年

1
hexdump中没有新行,因此grep可能无休止地在等待新行。cat工程自grep会得到一个EOF如果不换行,至少。也许尝试awk{作为RS?
muru 2014年

Answers:


4

您可以使用read命令(bash内置)强制将字符一一读取:

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

该脚本应打印所有带有balance {和的完整输出},但是您可以更改脚本以执行所需的任何操作。与几乎所有内容相比,此脚本在基准测试中效果不佳,但它非常简单,似乎对我有用。

请注意,您的测试样本不具有{和匹配},因此,如果是实际输入,则可能需要更改条件以打印行。


括号似乎不匹配只是因为他只发布了输出的开头。
2014年

8

答案在这里: grep在nc输出中不匹配

netcat将详细日志输出为标准错误,因此我们需要在捕获到grep之前捕获错误。

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

这个答案只是让我解决。当我运行不带的命令时,这真是很奇怪2>&1,看来grep根本不起作用。
Marecky

2

我认为问题在于netcat输出中没有换行符。我可以看到两种解决方法:

  1. 每秒钟插入一个换行符x(如果在的中间插入换行符,将会产生不幸的后果source):

    ( while sleep 1; do echo; done & netcat ... ) | grep source
    
  2. awk与换行符以外的其他RS一起使用:

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

仍然为空输出。为了确保命令正确,我在转储的流上运行- cat netcat_output | awk -v RS='}' -v ORS='}' '/sender/'输出正常:,"sender":"xbmc"}
tomekceszke 2014年

我刚检查 第一个解决方法,它就可以了!但是正如您提到的,它可以拆分输出,因此它不是最终解决方案。无论如何,非常感谢!
tomekceszke 2014年

1

添加--line-buffered对输出使用行缓冲:

netcat localhost 9090 | grep --line-buffered sender 

我已经尝试过了,但是没有用。
tomekceszke 2014年

1

使用watch命令:

watch 'netcat localhost 9090 | grep sender'

它也不起作用。与sed相同...但是,例如:netcat localhost 9090 | hexdump可以正常工作并将文本替换为hex live,为什么?
tomekceszke 2014年


0

在Bash中,您可以使用伪设备文件打开TCP连接并像往常一样grep。例如:

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

要测试它,只需运行可以发送一些文件的服务器,例如:

$ nc -vl 1234 < /etc/hosts

然后在另一个终端中运行测试到grep输出:

$ grep "127" < /dev/tcp/localhost/1234
127.0.0.1   localhost
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.