
estou tentando usarloginpara baixar grandes quantidades de dados e tenho tido problemas que resolvi ao sair prematuramente sem motivo aparente. Este é um script de teste simplificado:
#!/bin/bash exec > /tmp/lhook.out.txt 2> /tmp/lhook.err.txt nc -v server 4444 > /tmp/nc-test echo "Exit value: $?"
No servidor, quando executo um ouvinte nc simples como echo "Hello world. | nc -l 4444
, a transferência funciona corretamente. Mas quando quero transferir um arquivo maior, como o nc -l 4444 < /path/to/some/large.file
, o cliente transfere apenas uma pequena parte (às vezes 2kiB, às vezes ~250 kB). O valor de saída relatado é 0.
Ah, e claro - o mesmo script executado em Terminal.app dentro de uma sessão de usuário funciona bem.
Alguém pode ajudar na depuração, explicar o que está acontecendo ou fornecer uma solução?
EDITAR: Eu bisbilhotei dtruss
os syscalls do netcat e foi isso que consegui:
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
Suponho que, por algum motivo, o kernel esteja fornecendo nc EOF em vez de esperar por mais dados.
Responder1
Que descuido embaraçoso... :-(
nc
sai ao ler EOF do stdin. O cliente que recebe os dados executa o script LoginHook em um shell não interativo, que direciona nc
o descritor stdin de provavelmente para /dev/null
. Assim que lê EOF, ele é encerrado.
A correção é trivial: -d
chave de alimentação para o lado receptor. Isso evita que qualquer versão do netcat (BSD ou Linux) leia stdin e a transferência seja concluída sem problemas.