Як зібрати netcat вихід


13

Я намагаюся перехопити живий потік тексту 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
Жилль Кінот

@ user43791 вихід все ще порожній, але я впевнений, що netcat повернув відповідний рядок
tomekceszke

@sputnick цей одразу повертається до оболонки і не чекає події
tomekceszke

1
Нових рядків у hexdump немає, тому grep, ймовірно, нескінченно чекаємо нового рядка. catпрацює, оскільки grepотримає EOF, якщо не новий рядок, то принаймні. Може спробувати awkз , {як RS?
муру

Відповіді:


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

Цей скрипт повинен друкувати кожен повний висновок з регулювальної {і }, але ви можете змінити сценарій , щоб робити те , що ви хочете. Цей сценарій НЕ БУДЕ добре на еталоні порівняно з майже всім, але він досить простий і, здається, працює для мене ...

Зверніть увагу , що ваш тестовий зразок не мав відповідності {і }, тому , якщо це має місце реального введення, ви можете захотіти змінити критерії для друку лінії.


Схоже, невідповідні дужки - це лише тому, що він розмістив лише початок виводу.
Бармар

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

Я тільки перевірив перший спосіб вирішення, і він працює ! Але, як ви вже згадували, це може розділити вихід, тому не може бути остаточним рішенням. Все одно спасибі!
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 "sender" < /dev/tcp/example.com/1234

Щоб перевірити це, просто запустіть сервер, який може надіслати якийсь файл, наприклад:

$ nc -vl 1234 < /etc/hosts

Потім в іншому терміналі запустіть тест на grepвихід:

$ grep "127" < /dev/tcp/localhost/1234
127.0.0.1   localhost
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.