Lua: os.execute("sleep n") 在无限循环中不能被 ^C 停止
Lua: os.execute("sleep n") in infinite loop can't be stopped by ^C
在lua 5.2.4中,在无限循环中使用广泛使用的os.execute('sleep n')
方法时,无法通过^C
(Ctrl-C)停止程序。
最小示例:
while true do
print("HELLO!")
os.execute("sleep 3")
end
我的问题是:
这是预期的行为吗?我猜想程序在从 os.execute
命令返回后接收到 ^C
信号。
有没有"builtin"高效睡眠的方法?
Control-c 很可能被 os.execute
生成的 shell 捕获,而不是 Lua。您需要查看 os.execute
返回的代码。命令正常结束时,os.execute
returns true,"exit",rc.否则,它 returns nil 等。当它被 control-c 中断时,它在我的机器中 returns nil,"signal",2.
底线,试试这个代码:
while true do
print("HELLO!")
if not os.execute("sleep 3") then break end
end
简答
你的 sleep child 被终端的 SIGINT 杀死,但是 os.execute
忽略了信号,因此 lua 继续循环。
更长的答案
您的终端驱动程序将 Ctrl+C 转换为为前台进程组生成的 SIGINT,其中(至少)包括您的 lua进程及其childsleep进程。
(此信号极有可能在 lua 脚本位于 os.execute
内时生成,因为这是您的脚本花费大部分时间的地方是时候了。)
发生这种情况时,sleep 进程会立即被 SIGINT 终止。然而,lua 进程忽略了信号。
它忽略 SIGINT 因为 os.execute
是传统库调用的包装器 system
, as you can see in the source:
static int os_execute (lua_State *L) {
const char *cmd = luaL_optstring(L, 1, NULL);
int stat = system(cmd); /* <<<<<<<<<<<<<<< here <<<<<<<<<<<<< */
if (cmd != NULL)
return luaL_execresult(L, stat);
else {
lua_pushboolean(L, stat); /* true if there is a shell */
return 1;
}
}
此库调用具有非常具体的语义,包括忽略调用者中的 SIGINT。
在lua 5.2.4中,在无限循环中使用广泛使用的os.execute('sleep n')
方法时,无法通过^C
(Ctrl-C)停止程序。
最小示例:
while true do
print("HELLO!")
os.execute("sleep 3")
end
我的问题是:
这是预期的行为吗?我猜想程序在从
os.execute
命令返回后接收到^C
信号。有没有"builtin"高效睡眠的方法?
Control-c 很可能被 os.execute
生成的 shell 捕获,而不是 Lua。您需要查看 os.execute
返回的代码。命令正常结束时,os.execute
returns true,"exit",rc.否则,它 returns nil 等。当它被 control-c 中断时,它在我的机器中 returns nil,"signal",2.
底线,试试这个代码:
while true do
print("HELLO!")
if not os.execute("sleep 3") then break end
end
简答
你的 sleep child 被终端的 SIGINT 杀死,但是 os.execute
忽略了信号,因此 lua 继续循环。
更长的答案
您的终端驱动程序将 Ctrl+C 转换为为前台进程组生成的 SIGINT,其中(至少)包括您的 lua进程及其childsleep进程。
(此信号极有可能在 lua 脚本位于 os.execute
内时生成,因为这是您的脚本花费大部分时间的地方是时候了。)
发生这种情况时,sleep 进程会立即被 SIGINT 终止。然而,lua 进程忽略了信号。
它忽略 SIGINT 因为 os.execute
是传统库调用的包装器 system
, as you can see in the source:
static int os_execute (lua_State *L) {
const char *cmd = luaL_optstring(L, 1, NULL);
int stat = system(cmd); /* <<<<<<<<<<<<<<< here <<<<<<<<<<<<< */
if (cmd != NULL)
return luaL_execresult(L, stat);
else {
lua_pushboolean(L, stat); /* true if there is a shell */
return 1;
}
}
此库调用具有非常具体的语义,包括忽略调用者中的 SIGINT。