如何对需要 sudo 的命令使用 bash 超时功能?

如何对需要 sudo 的命令使用 bash 超时功能?

在 Bash 中,这将设置 10 秒的时间限制慢命令

timeout 10 slowcommand

我想知道如果我必须打电话的话我怎么能得到同样的行为须藤为了运行慢命令, IE:

timeout 10 sudo slowcommand

这将限制时间须藤,不在慢命令...使用 sudo 时有没有一种优雅的方法来做到这一点?

编辑:让我们假设暂停不允许与 sudo 一起运行。

答案1

timeout不是bashshell 或任何 shell 的内置/函数(除非您想考虑 busybox sh,其中 busybox 命令可以被视为 shell 的内置命令)。

timeout是一个非标准的独立实用程序,其中存在几个通常不兼容的实现(也存在timelimit具有相同功能的实用程序)。

在:

timeout 10 sudo slowcommand

timeout实用程序的 GNU 实现的当前版本(来自 GNU coreutils,再次不同于 GNU shell ),如果在 10 秒内未完成,则bash运行sudo slowcommand并向其自己的进程组发送 SIGTERM 命令。sudo

然而,正在运行的进程已经更改了用户ID,并且生成运行的sudo进程也将以不同的uid运行,因此即使两个进程与正在运行的进程位于同一进程组中,也无权向他们。sudoslowcommandtimeouttimeout

有一些可能的方法可以解决这个问题。您可以安排内核发送一些信号,而不是发送一些像正在运行的非特权进程timeout。例如,您可以让它发送:

  • SIGPIPE 如果slowcommand写入关闭的管道:

    sudo slowcommand | timeout 10 cat
    

    slowcommand如果 10 秒后向 stdout 写入内容,则会导致发送 SIGPIPE 。

    (顺便说一句,这里 、catsudoslowcommand都将在同一个进程组中运行,因此与 )相同timeout 10 sudo slowcommand | cat)。

  • SIGXCPU 如果slowcommand使用的 CPU 时间超过其分配的限制:

    (ulimit -t 10; exec sudo slowcommand)
    

    如果它使用 10 秒的 CPU 时间,就会导致slowcommand被杀死。

  • SIGHUP 如果终端挂断,并且sudo不是会话领导者:

    timeout 10 script -qfc 'sudo slowcommand; exit' /dev/null
    

    (这里假设util-linux脚本)

  • 信号/信号退出。您还可以使用expect// zpty/之类的东西来模拟终端,并在 10 秒后发送一个字符script,以便将 SIGINT 发送到该终端的前台进程组。screen^C

相关内容