我正在尝试使用登录钩子下载大量数据时,我遇到了一些问题,我发现 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
,客户端只会传输一小部分(有时是 2kiB,有时是 ~250 kiB)。报告的退出值为 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
从 stdin 读取 EOF 后退出。接收数据的客户端在非交互式 shell 中运行 LoginHook 脚本,该脚本将nc
的 stdin 描述符(可能)定向到/dev/null
。一旦从中读取 EOF,它就会退出。
修复很简单:-d
为接收端提供交换机。这可以防止任何版本的 netcat(BSD 或 Linux)读取 stdin,并且传输可以顺利完成。