Bash 中的 timeout 命令
本文是使用 Bash 中 GNU 的 coreutils 包的 timeout 命令为特定程序设置超时的简单指南。
Bash 中的 timeout 命令
在许多情况下,例如从服务器获取数据或使用随机输入运行函数或程序,程序或函数可能会运行很长时间或无限期地运行。
在这种情况下,停止程序并防止它浪费更多的时间和资源是必不可少的。
这就是超时功能的用武之地。用户定义一个时间限制,然后允许程序运行直到成功完成,如果在用户定义的时间限制之前花费的时间太长,则程序将被终止。
大多数编程语言通常内置超时功能。 但是,对于 Bash,它不是内置的,而是名为 coreutils 的外部包的一部分。
这个包由 GNU 开发和维护,包含许多基本实用程序的实现。
只需在 LINUX 系统中运行命令 sudo apt-get install -y coreutils
即可安装 coreutils 包。
您必须先安装 Homebrew 才能在 macOS 系统上获取 coreutils。 要获取 Homebrew,请在命令终端中运行以下命令。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
完成 Homebrew 安装后,运行以下命令。
brew install coreutils
如果你安装了 coreutils 包,你可以简单地使用超时功能,例如:
timeout 10 ping baidu.com
Bash 中的 ping 实用程序是内置的,并且会继续运行直到手动中断。 默认情况下,ping 每 1 秒发送一个包。
如上所示,超时命令在 10 秒后终止 ping,因为超时命令后的数字是时间限制。
因此,命令 timeout 10 cmd1 表示 cmd1 将运行直到成功完成或 10 秒,以较早者为准。 超时命令的时间单位是秒。
要使用以分钟、小时或天为单位的时间值,请分别添加 m、h 或 d。
例如,要设置 2 分钟的超时:
timeout 2m programToRun
需要注意的是,当进程超时时,超时的退出状态为124。 在下面的示例中,我们将使用它来检查进程是否超时。
timeout 1 ping 8.8.8.8 -w3
EXIT_STATUS=$?
if [ $EXIT_STATUS -eq 124 ]
then
echo 'Process timed out!'
else
echo 'Process did not timeout.'
fi
exit $EXIT_STATUS
在上述示例中,如果进程未在 1 秒内完成,则进程将超时。 -w3
扩展表示该地址将被 ping 三次。
因此,此过程将始终超时,并给出以下输出。
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=40.4 ms
Process timed out!
重要的是要注意任何内部超时也会导致相同的退出状态 (124)。 因此,此输出表明进程使用我们指定的超时超时或某些内部超时使其终止。
在 Bash 中使用超时和 SIGKILL 信号
通常,超时函数会在达到时间限制时发送 SIGTERM 信号以停止程序的执行。 问题是某些程序可能会忽略 SIGTERM 信号并继续运行。
这就是 SIGKILL 信号出现的地方; 它立即停止执行一个进程及其所有子进程,并且不能被阻止或忽略。 要使用 SIGKILL 超时,我们必须添加 -s 标志。
例如:
timeout -s SIGKILL 10 programToRun
当不直接从 shell 运行 timeout
时,就像从脚本运行它一样,将 --foreground 添加到 timeout
命令很重要。
可以使用超时命令的许多替代方法,所有这些都主要基于相同的逻辑,即在睡眠时使用一些终止信号,然后运行所需的命令或程序,一旦睡眠结束,这些命令或程序就会停止。
例子:
(sleep 2 && killall prog) & ./prog
如果 prog 还没有完成执行,上面的代码将在 2 秒后杀死 prog
的所有进程。 这样的解决方案可以工作,但不如 timeout 命令安全可靠,因此最好改用 timeout。
相关文章
在 Bash 中启动一个新的终端会话
发布时间:2023/06/11 浏览次数:102 分类:操作系统
-
在各种情况下,当使用 Bash 或其他 shell 时,可能需要在新终端实例或同一终端中的另一个选项卡中运行脚本或程序。
在 Bash 中检查语法
发布时间:2023/06/11 浏览次数:97 分类:操作系统
-
在 Bash 脚本中情况并非如此,因为 Bash 是一个命令行解释器。 因此,我们需要单独检查语法错误。可以有不同的技术来检查语法问题,如下所示。
使用 Bash 对文本文件中的数字列表求和
发布时间:2023/06/11 浏览次数:109 分类:操作系统
-
本篇文章将介绍使用 Bash 脚本对文件中的数字列表求和的多种方法。 第一种方法涉及使用粘贴命令,我们将讨论两种情况:使用现有文件和使用标准输入读取文件。
在 Bash 中传递所有参数
发布时间:2023/06/11 浏览次数:197 分类:操作系统
-
在 Bash 脚本中,我们主要使用语法 $1 $2 $3 ... $N 在函数中传递变量。此外,我们将看到必要的示例和解释,以使主题更容易理解。在 Bash 中传递所有参数
在 Bash 中解析 XML
发布时间:2023/06/11 浏览次数:109 分类:操作系统
-
本文将展示我们如何通过 Bash 解析 XML。我们将在这里讨论两个库。 我们的第一个库是 xmllint,第二个库称为 XMLStarlet。在 Bash 中使用 xmllint 解析 XML
Bash 脚本中的 Echo Tab 字符
发布时间:2023/06/11 浏览次数:198 分类:操作系统
-
本文演示了如何回显特殊字符(例如制表符),否则这些字符会在 Bash 脚本中转换为单个空格字符。 这扩展到 Bash 以外的 shell(例如 zsh)。
在 Bash 中回显到 stderr
发布时间:2023/06/11 浏览次数:102 分类:操作系统
-
本文将了解 stderr 及其功能。 此外,我们将查看一些示例,这些示例将使该主题更容易理解。在 Bash 中回显到 stderr 命令 stderr 主要用于在执行任何命令期间保持错误的重新编码。
在 Bash 中连接多个文件
发布时间:2023/06/10 浏览次数:170 分类:操作系统
-
有时出于各种目的,我们需要将多个文件连接成一个文件。 在 Bash 脚本中,很容易完成这项任务。在 Bash 中连接多个文件
在 Bash 中打开 Emacs
发布时间:2023/06/10 浏览次数:50 分类:操作系统
-
本文将展示我们如何在 Bash 中打开 Emacs。 我们还将讨论如何安装 Emacs 文本编辑器。在您的系统中安装 EMACS 假设您的系统中没有 Emacs。