Làm thế nào để grep netcat đầu ra


13

Tôi đang cố gắng grep luồng văn bản trực tiếp từ netcatnhưng nó không hoạt động với tôi:

netcat localhost 9090 | grep sender

trả lại không có gì, nhưng tôi chắc chắn rằng nó nên.

Nếu tôi chuyển hướng netcatđầu ra thành một tệp và thêm một số độ trễ (mô phỏng môi trường thực) - thì nó hoạt động:

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

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

Tôi cũng đã cố gắng để thêm --line-bufferednhưng không thành công.

Tôi đã làm gì sai?

Biên tập:

Tôi nhận thấy vấn đề tương tự với sed, đầu ra là trống rỗng.

Nhưng, ví dụ, hexdumpchuyển đổi văn bản thành hex trực tiếp:

$ 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
Có lẽ nó được đệm trong đường ống? Bạn có thể thử sử dụng stdbuf -o0 netcat localhost 9090 | grep sender(lấy từ đây )
user43791

Nó hoạt động như thế này? netcat -z localhost 9090 | grep sender
Gilles Quenot

@ user43791 đầu ra vẫn trống, nhưng tôi chắc chắn rằng netcat đã trả về chuỗi khớp
tomekceszke

@sputnick cái này ngay lập tức trở lại vỏ và không chờ đợi một sự kiện
tomekceszke

1
Không có dòng mới trong hexdump, vì vậy grepcó lẽ đang chờ đợi vô tận cho một dòng mới. cathoạt động vì grepsẽ nhận được EOF nếu không phải là một dòng mới, ít nhất. Có thể thử awkvới {RS?
muru

Câu trả lời:


4

Bạn có thể sử dụng readlệnh ( bashdựng sẵn) để buộc các ký tự được đọc từng cái một:

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

Tập lệnh này sẽ in mọi đầu ra đầy đủ với sự cân bằng {}, nhưng bạn có thể thay đổi tập lệnh để làm bất cứ điều gì bạn muốn. Kịch bản này sẽ KHÔNG làm tốt trên điểm chuẩn so với hầu hết mọi thứ, nhưng nó khá đơn giản và dường như hoạt động với tôi ...

Lưu ý rằng mẫu thử nghiệm của bạn không khớp {}vì vậy, nếu đây là trường hợp của đầu vào thực, bạn có thể muốn thay đổi tiêu chí để in dòng.


Hình như niềng răng không khớp chỉ là do anh ta chỉ đăng phần đầu của đầu ra.
Barmar

8

Trả lời ở đây: grep không khớp trong đầu ra nc

netcat đưa ra các bản ghi dài dòng cho lỗi tiêu chuẩn, vì vậy chúng tôi cần phải nắm bắt các lỗi trước khi chuyển sang grep.

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

Câu trả lời này chỉ làm cho tôi giải pháp. Điều đó rất lạ khi tôi chạy lệnh đó mà không có 2>&1vẻ như grep hoàn toàn không hoạt động.
Marecky

2

Tôi nghĩ vấn đề là sự vắng mặt của dòng mới trong netcatđầu ra. Tôi có thể thấy hai cách giải quyết:

  1. Chèn một dòng mới mỗi xgiây (với những hậu quả đáng tiếc nếu dòng mới được chèn vào giữa source):

    ( while sleep 1; do echo; done & netcat ... ) | grep source
    
  2. Sử dụng awkvới RS khác với dòng mới:

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

Vẫn đầu ra trống. Để đảm bảo lệnh đó đúng, tôi chạy trên luồng bị đổ - cat netcat_output | awk -v RS='}' -v ORS='}' '/sender/'Đầu ra vẫn ổn:,"sender":"xbmc"}
tomekceszke

Tôi chỉ kiểm tra cách giải quyết đầu tiên và nó hoạt động ! Nhưng như bạn đã đề cập, nó có thể phân chia đầu ra để nó không thể là giải pháp cuối cùng. Dù sao cũng cảm ơn nhiều!
tomekceszke

1

Thêm --line-bufferedđể sử dụng bộ đệm dòng trên đầu ra:

netcat localhost 9090 | grep --line-buffered sender 

Tôi đã thử điều này, nó không hoạt động.
tomekceszke

1

sử dụng watchlệnh:

watch 'netcat localhost 9090 | grep sender'

Nó cũng không hoạt động. Tương tự với sed ... Nhưng, ví dụ, cái này: netcat localhost 9090 | hexdump hoạt động và thay thế văn bản thành hex live, tại sao?
tomekceszke


0

Trong Bash, bạn có thể sử dụng các tệp thiết bị giả để mở kết nối TCP và grep nó như bình thường. Ví dụ:

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

Để kiểm tra nó, chỉ cần chạy máy chủ có thể gửi một số tệp, như:

$ nc -vl 1234 < /etc/hosts

Sau đó, trong một thiết bị đầu cuối khác chạy thử nghiệm đến grepđầu ra:

$ grep "127" < /dev/tcp/localhost/1234
127.0.0.1   localhost
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.