很棒的 WM - os.execute 与 afwul.spawn

str*_*tle 1 awesome-wm

我想知道 lua 之间是否有任何区别

os.execute('<command>')
Run Code Online (Sandbox Code Playgroud)

和很棒的

awful.spawn('<command>')
Run Code Online (Sandbox Code Playgroud)

我注意到 lain建议使用os.execute,是否有任何理由,或者这是个人品味的问题?

Emm*_*lee 7

永远不要使用os.executeio.popen。它们会阻塞功能并导致非常糟糕的性能和显着增加的输入(鼠标/键盘)和客户端重绘延迟。使用这些函数是一种反模式,只会让一切变得更糟。

请参阅文档https://awesomewm.org/apidoc/libraries/awful.spawn.html 中的警告

现在要真正回答这个问题,您必须了解 Awesome 是单线程的。这意味着它一次只做一件事。如果您调用os.execute("sleep 10"),您的鼠标将继续移动,但您的计算机将被冻结 10 秒钟。对于执行速度足够快的命令,可能会错过这一点,但请记住,由于延迟/频率规则,任何需要 33 毫秒执行时间的命令将在 60fps 视频游戏中最多下降 2 帧(并且至少丢一个)。如果您每秒有许多命令,它们会累加并破坏您的系统性能。

但是,Awesome 并不注定会变慢。它可能没有多个线程,但它有一个叫做协程的东西,也有回调。这意味着需要时间执行的事情仍然可以在后台执行(使用 C 线程或外部进程 + 套接字)。完成后,他们可以通知 Awesome 线程。这完美地工作并且避免阻塞Awesome。

现在我们进入下一部分。如果我做:

-- Do **NOT** do this.
os.execute("sleep 1; echo foo > /tmp/foo.txt")
mylabel.text = io.popen("cat /tmp/foo.txt"):read("*all*")
Run Code Online (Sandbox Code Playgroud)

标签将显示foo。但如果我这样做:

-- Assumes /tmp/foo.txt does not exist
awful.spawn.with_shell("sleep 1; echo foo > /tmp/foo.txt")
mylabel.text = io.popen("cat /tmp/foo.txt"):read("*all*")
Run Code Online (Sandbox Code Playgroud)

那么标签将是空的。awful.spawn并且awful.spawn.with_shell阻塞,因此io.popen将前执行wayyysleep 1饰面。这就是为什么我们有异步函数来执行 shell 命令。有许多具有不同特征和复杂性的变体。awful.spawn.easy_async是最常见的,因为它对于一般的“我想执行一个命令并在它完成时对输出做一些事情”来说已经足够了。

awful.spawn.easy_async_with_shell("sleep 1; echo foo > /tmp/foo.txt", function()
    awful.spawn.easy_async_with_shell("cat /tmp/foo.txt", function(out)
        mylabel.text = out
    end)
end)
Run Code Online (Sandbox Code Playgroud)

在这个变体中,Awesome 不会阻塞。同样,与其他 spawn 一样,您不能在回调函数之外添加代码以使用命令的结果。代码将在命令完成之前执行,因此结果尚不可用。

还有一种叫做协程的东西,它不需要回调,但目前很难在 Awesome 中使用,而且解释起来也很混乱。