我有一个非常基本的Linux脚本(/home/scripts/script.sh(:
#!/bin/bash
echo 'a' | /bin/netcat -vv 10.10.10.1 3333
echo "done" > /tmp/result
当我尝试从 shell 运行它时,它工作正常。所以脚本很好(也,完成被写入/tmp/result 文件(:
# /home/scripts/script.sh
10.10.10.1: inverse host lookup failed: Unknown host
(UNKNOWN) [10.10.10.1] 3333 (?) open
AABBCCDDEEF
sent 2, rcvd 13
#
但是,当我尝试从前台守护程序中的C++代码运行它时:
const char **argv = new const char* [3];
argv[0] = "/home/scripts/script.sh";
argv[1] = "/home/scripts/script.sh";
argv[2] = NULL;
execv(argv[0], const_cast<char**>(&argv[1]));
在短时间内效果很好(3-5分钟(。 在那一小段时间之后,脚本运行失败,nc 的返回码为 1,这是输出:
10.10.10.1: inverse host lookup failed: Unknown host
(UNKNOWN) [10.10.10.1] 3333 (?) open
Preposterous fd value 17
sent 0, rcvd 0
为什么 fd 值是荒谬的?我的守护程序在前 3-5 分钟内打开了一些文件,也许 netcat 无法像 fd 那样处理更大的数字?
在这个问题上,我该如何克服?
此问题是由 netcat 引起的。
首先,我没有意识到这条消息的重要性:
Preposterous fd value 17
这实际上是netcat的一个非常重要的错误消息,因为它不是为默认使用高于16的fds而设计的,这对于简单的脚本来说是完全可以接受的。
但是,在多线程环境中,当调用 netcat 时,可能已经使用了超过 16 个 fd。
这是来自 2007 年的消息,它将 16 更新为 1024 作为错误修复。
Netcat的官方网页是 https://nc110.sourceforge.io,当前版本是1.10,仍然将FD_SETSIZE定义为16。
解决方案是获取代码,修补并构建它。
只是一个快速的答案:在 debian 中,我解决了安装netcat-openbsd的这个问题。 默认的netcat指的是netcat-tradition,它仍然有这个错误。