当前位置 : 主页 > 手机开发 > 其它 >

套接字 – os.execute没有继承父级的fds

来源:互联网 收集:自由互联 发布时间:2021-06-19
我有一个类似于这里描述的问题: Prevent fork() from copying sockets 基本上,在我的Lua脚本中,我正在生成另一个脚本: 不需要以任何方式与我的脚本通信 我的脚本完成后继续运行 是第三方程
我有一个类似于这里描述的问题:
Prevent fork() from copying sockets

基本上,在我的Lua脚本中,我正在生成另一个脚本:

>不需要以任何方式与我的脚本通信
>我的脚本完成后继续运行
>是第三方程序,我无法控制的代码

问题是我的Lua脚本打开一个TCP套接字来监听特定端口并在它退出后,尽管有一个显式服务器:close()子(或更具体地说是它的子)保持在套接字上并保持端口打开(在LISTEN状态)阻止我的脚本再次运行.

这是演示问题的示例代码:

require('socket')

print('listening')
s = socket.bind("*", 9999)
s:settimeout(1)

while true do
    print('accepting connection')
    local c = s:accept()
    if c then
            c:settimeout(1)
            local rec = c:receive()
            print('received ' .. rec)
            c:close()
            if rec == "quit" then break end
            if rec == "exec" then 
                    print('running ping in background')
                    os.execute('sleep 10s &')
                    break
            end     
    end
end
print('closing server')
s:close()

如果我运行上面的脚本并回显退出| nc localhost 9999一切正常 – 程序退出并关闭端口.

但是,如果我做回声exec | nc localhost 9999程序退出,但端口被生成的睡眠阻止(由netstat -lpn确认),直到它退出.

我如何以最简单的方式解决这个问题,最好不要添加任何额外的依赖项.

我发现了一个更简单的解决方案,它利用了os.execute(cmd)在shell中运行cmd的事实,事实证明,它能够关闭文件描述符,如下所示:

> http://linux.die.net/man/1/ash(部分重定向)
> http://www.gnu.org/software/bash/manual/bashref.html#Redirections

例如(在灰中测试):

exec 3<&-                                      # closes fd3
    exec 3<&- 4<&-                                 # closes fd3 and fd4
    eval exec `seq 1 255 | sed -e 's/.*/&<\&-/'`   # closes all file descriptors

所以在我的基于luasocket的示例中,它足以替换:

os.execute('sleep 10s &')

有:

os.execute("eval exec `seq 1 255 | sed -e 's/.*/&<\\&-/'`; sleep 10s &")

这将关闭所有文件描述符,包括我的服务器套接字,然后执行实际命令(此处为sleep 10s),以便在脚本退出后不会占用端口.它还有处理stdout和stderr重定向的好处.

这比使用Lua的限制更加紧凑和简单,并且不需要任何额外的依赖性.感谢#uclibc,我从嵌入式Linux工作人员那里得到了一些关于最终shell语法的精彩帮助.

网友评论