Lua:无限循环中的os.execute(“sleep n”)无法被^ C停止

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lua:无限循环中的os.execute(“sleep n”)无法被^ C停止相关的知识,希望对你有一定的参考价值。

在lua 5.2.4中,当在无限循环中使用广泛使用的os.execute('sleep n')方法时,程序不能被^C(Ctrl-C)停止。

最小的例子:

while true do
    print("HELLO!")
    os.execute("sleep 3")
end

我的问题是:

  1. 这是预期的行为吗?我会猜到程序在从^C命令返回后收到os.execute信号。
  2. 是否有“内置”的方式有效地入睡?
答案

简答

您的睡眠孩子被终端的SIGINT杀死,但是os.execute忽略了信号,因此lua继续循环。

更长的答案

您的终端驱动程序将Ctrl + C转换为为前台进程组生成的SIGINT,其中包括(至少)您的lua进程及其子进程。

(当lua脚本在os.execute中时,这个信号极可能被生成,因为那是你的脚本花费大部分时间的地方。)

当发生这种情况时,SIGINT会立即终止睡眠过程。然而,lua过程忽略了信号。

它忽略了SIGINT,因为os.execute是传统库调用system的包装器,你可以看到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。

另一答案

Control-c最有可能被os.execute而不是Lua生成的shell捕获。你需要查看os.execute返回的代码。当命令正常结束时,os.execute返回true,“exit”,rc。否则,它返回nil等。当它被control-c中断时,它在我的机器中返回nil,“signal”,2。

底线,试试这段代码:

while true do
    print("HELLO!")
    if not os.execute("sleep 3") then break end
end

以上是关于Lua:无限循环中的os.execute(“sleep n”)无法被^ C停止的主要内容,如果未能解决你的问题,请参考以下文章

在 Lua 中取回 os.execute 的输出

[编程]lua有暂停运行的函数吗?

车辆生成菜单在lua中无限循环

如何使用 Lua 运行可执行文件?

lua调用shell 脚本

LUA中获得服务器IP