วิธี 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แปลงข้อความเป็น hex live:

$ 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

@ user43791 เอาท์พุทยังคงว่างเปล่า แต่ฉันแน่ใจว่า netcat ส่งคืนสตริงที่ตรงกัน
tomekceszke

@sputnick อันนี้กลับมาสู่เชลล์ทันทีและไม่รอเหตุการณ์
tomekceszke

1
ไม่มีบรรทัดใหม่ใน hexdump ดังนั้นgrepอาจรอการขึ้นบรรทัดใหม่อย่างไม่สิ้นสุด catทำงานได้ตั้งแต่grepจะได้รับ EOF หากไม่ใช่บรรทัดใหม่อย่างน้อย อาจลองawkด้วย{RS
muru

คำตอบ:


4

คุณสามารถใช้readคำสั่ง ( bashbuiltin) เพื่อบังคับอักขระให้อ่านทีละตัว:

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

สคริปต์นี้ควรพิมพ์เอาต์พุตเต็มรูปแบบด้วยการปรับสมดุล{และ}แต่คุณสามารถเปลี่ยนสคริปต์เพื่อทำสิ่งที่คุณต้องการ สคริปต์นี้จะไม่ทำงานได้ดีเมื่อเทียบกับมาตรฐานอะไรมาก แต่มันค่อนข้างง่ายและดูเหมือนว่าจะเหมาะกับฉัน ...

โปรดทราบว่าตัวอย่างทดสอบของคุณไม่มีการจับคู่{และ}ดังนั้นหากเป็นกรณีของอินพุตจริงคุณอาจต้องการเปลี่ยนเกณฑ์ในการพิมพ์บรรทัด


ดูเหมือนว่าวงเล็บปีกกาไม่ตรงกันนั้นเป็นเพราะเขาโพสต์เฉพาะจุดเริ่มต้นของเอาต์พุตเท่านั้น
Barmar

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

1

เพิ่ม--line-bufferedเพื่อใช้การบัฟเฟอร์บรรทัดบนเอาต์พุต:

netcat localhost 9090 | grep --line-buffered sender 

ฉันลองสิ่งนี้แล้วมันใช้งานไม่ได้
tomekceszke

1

ใช้watchคำสั่ง:

watch 'netcat localhost 9090 | grep sender'

มันไม่ทำงานเหมือนกัน เช่นเดียวกับ sed ... แต่ตัวอย่างเช่น: netcat localhost 9090 | hexdump ทำงานและแทนที่ข้อความเป็น hex live ทำไม
tomekceszke


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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.