
Я пытаюсь использоватьloginhookдля загрузки больших объемов данных и у меня возникли проблемы, которые я свел к преждевременному завершению работы nc без видимых причин. Это упрощенный тестовый скрипт:
#!/bin/bash exec > /tmp/lhook.out.txt 2> /tmp/lhook.err.txt nc -v server 4444 > /tmp/nc-test echo "Exit value: $?"
На сервере, когда я запускаю простой nc-слушатель, например echo "Hello world. | nc -l 4444
, передача работает правильно. Но когда я хочу передать файл большего размера, например nc -l 4444 < /path/to/some/large.file
, клиент передает только небольшую часть (иногда 2 КБ, иногда ~250 КБ). Выходное значение, о котором сообщается, равно 0.
О, и конечно же — тот же скрипт, выполненный в Terminal.app внутри сеанса пользователя, работает отлично.
Может ли кто-нибудь помочь с отладкой, объяснить, что происходит, или предложить решение?
РЕДАКТИРОВАТЬ: Я просмотрел dtruss
системные вызовы netcat и вот что получил:
157/0x4c6: write(0x1, "j,\350\037\376\377\377\203\304$f\211F\016\350&f\004\0", 0x400) = 1024 0
157/0x4c6: select(0x5, 0x7FFF53A87B40, 0x0, 0x0, 0x0) = 1 0
157/0x4c6: read(0x4, "\001u\374)u\f\215\f6\203\304\020\003\331\001\b\353\035\017\267\003\213\027P\213\317\377R\004\271\377\377\0", 0x400)
= 1024 0
157/0x4c6: write(0x1, "\001u\374)u\f\215\f6\203\304\020\003\331\001\b\353\035\017\267\003\213\027P\213\317\377R\004\271\377\377\0", 0x400)
= 1024 0
157/0x4c6: select(0x5, 0x7FFF53A87B40, 0x0, 0x0, 0x0) = 1 0
157/0x4c6: read(0x4, "\0", 0x400) = 0 0
157/0x4c6: shutdown(0x4, 0x0, 0x0) = -1 Err#57
157/0x4c6: close(0x4) = 0 0
157/0x4c6: close(0x3) = 0 0
157/0x4c6: close(0x3) = -1 Err#9
Я предполагаю, что по какой-то причине ядро выдает nc EOF вместо того, чтобы дождаться дополнительных данных.
решение1
Какая досадная оплошность... :-(
nc
завершается после чтения EOF из stdin. Клиент, который получает данные, запускает скрипт LoginHook в неинтерактивной оболочке, которая направляет nc
дескриптор stdin , вероятно, в /dev/null
. Как только он читает из него EOF, он завершается.
Исправление тривиально: поставьте -d
переключатель на принимающую сторону. Это не даст ни одной из версий netcat (BSD или Linux) читать stdin, и передача завершится без проблем.