Linux timeout 命令完全指南:指定固定时间并发送固定信号

Linux timeout 命令完全指南:指定固定时间并发送固定信号

日常运维中,我们经常需要运行一些可能"卡住"的命令------压测脚本、爬虫、抓包工具、长任务进程。它们平时运行正常,但偶尔会因为网络抖动、死锁、等待输入等原因一直不退出 ,把终端或后台任务死死占住。这时候,timeout 命令就是最省心的"保险丝"。

一、timeout 能做什么

timeout 是 GNU coreutils 自带的一个命令,作用是:运行一个命令,若它在指定时间内没有结束,就向它发送一个信号,强制或优雅地把它终止。

它解决的核心痛点是:

  • 命令卡死时能自动超时退出,不用人工 Ctrl+C
  • 可以灵活指定"超时多久"、"到时发什么信号"
  • 避免长任务无限期占用系统资源

二、基本语法

bash 复制代码
timeout [选项] 持续时间 命令 [参数...]

其中"持续时间"就是超时阈值,后面的 命令 参数 是真正要执行的内容。

三、指定固定时间

时间可以直接写数字,也可以带后缀。默认单位是秒,后缀 s 表示秒、m 表示分钟、h 表示小时、d 表示天。

bash 复制代码
# 10 秒(不带后缀默认秒)
timeout 10   mycmd

# 显式写 10 秒,更清晰
timeout 10s  mycmd

# 5 分钟
timeout 5m   mycmd

# 2 小时
timeout 2h   mycmd

小提示:timeout 10 和 timeout 10s 是等价的。为了可读性,建议显式加上单位后缀。

四、指定固定信号

到点之后,timeout 默认发送 SIGTERM (信号 15)。我们可以用 -s / --signal= 指定到底发送哪种信号:

bash 复制代码
# 到时发送 SIGINT(Ctrl+C 的等效信号,2 号)
timeout --signal=INT  10s  mycmd

# 到时发送 SIGTERM(默认,15 号)
timeout --signal=TERM 10s  mycmd

# 到时直接 SIGKILL(9 号,无法被捕获,立即强杀)
timeout -s KILL       10s  mycmd

信号既可以写名称(INT、TERM、KILL),也可以写数字(2、15、9)。

常见的信号选择逻辑:

信号 数字 行为 适用场景
SIGTERM 15 优雅终止,进程可捕获并清理 默认选择,多数场景
SIGINT 2 相当于手动 Ctrl+C 希望模拟用户中断
SIGKILL 9 立即强杀,无法被捕获 兜底,进程彻底不响应时

五、完整示例深度解读

你可能会在实际脚本里看到这样一条命令:

bash 复制代码
timeout --signal=INT --kill-after=10s 10s \ ngauge /root/ngauge-test-20260929/config.yml

我们来拆解它的每一部分含义:

  • timeout:超时控制命令
  • --signal=INT:到点时发送 SIGINT 信号,让 ngauge 优雅地收尾
  • --kill-after=10s:发送 SIGINT 之后再给 10 秒缓冲时间
  • 10s:总共运行 10 秒,到时触发超时
  • ngauge /root/ngauge-test-20260929/config.yml:实际要运行的命令及其参数

执行的完整时间线:

  1. 启动 ngauge,加载 config.yml 开始压测
  2. 运行 10 秒后,timeout 向 ngauge 发送 SIGINT,通知它"该停了,自己清理"
  3. 此时 ngauge 有机会保存数据、关闭连接、释放资源(不会立即被杀掉)
  4. 如果 ngauge 在 10 秒的缓冲期内正常退出,流程就顺利结束
  5. 如果 ngauge 收到 SIGINT 后 10 秒内仍然不死,--kill-after 触发,发送 SIGKILL 强制杀死

一句话总结 :这是非常经典的"先优雅后强制"的停止策略------给进程一次体面退出的机会,实在不行再动刀。

六、为什么这样设计很有用

很多服务类工具收到 SIGINT 后会做资源清理:比如压测工具要关闭网络连接、抓包工具要落盘保存数据、数据库客户端要提交事务。如果一上来就发 SIGKILL,这些数据可能直接丢失或损坏。

而 --kill-after 正好弥补了"发了优雅信号但进程仍卡死"的漏洞,保证一定能在某个时间点杀掉进程,不会无限期挂住。这对脚本、CI、定时任务里的防挂死处理特别有价值。

七、其他常用选项

timeout 还有几个实用的参数:

bash 复制代码
# 超时后保留命令的退出码,方便脚本判断失败原因
timeout --preserve-status 10s mycmd

# 在前台模式下运行(配合管道使用,避免无法获取子进程输出)
timeout --foreground 10s cmd | tee log.txt

# 把超时时长作为第一个参数传给命令(少见,但存在)
timeout --timeout=10s mycmd
  • --preserve-status:超时杀掉命令后,返回 127 还是命令实际退出码由它决定,用于脚本精确判断"是超时了还是真出错了"。
  • --foreground:当 timeout 和管道、后台作业一起用,无法往子进程发信号时使用。

八、总结

timeout 是一个小而美的命令,核心要素只有两个:

  1. 时间:告诉它"多久算超时"
  2. 信号:告诉它"超时后怎么处理"

再配合 --kill-after,就能实现"给机会、不无限等 "的优雅停止策略。下次再写压测、抓包或长任务脚本,别忘了给它上一道 timeout 保险丝。

相关推荐
SunnyDays10111 小时前
如何使用 Python 将 PowerPoint(PPT 或 PPTX)转换为 Markdown
python·ppt转markdown·pptx转markdown·powerpoint转md
PiaoKe___1 小时前
云手机原理与 Python 自动化实战:ADB、REST API、WebSocket 群控入门
python·智能手机·自动化
co_wait1 小时前
Python 迭代器(一)
python
Yolanda_20223 小时前
15.dataloader的使用
python
杨杨杨大侠10 小时前
Jev、Kev、Laya:决策模型怎么选,什么时候需要微调?
人工智能·python·agent
LOVE️YOU10 小时前
Python 在定义函数时,究竟定义的是什么?
python
段一凡-华北理工大学10 小时前
大模型应用开发 100 天:Python + LLM 从入门到精通 day26~Prompt 调试与优化——A/B 测试与效果评估
windows·python·大模型·prompt·智能体·提示词工程·高炉智能化
Minecraft红客11 小时前
以撒的结合
python·游戏·电脑·娱乐
Circ.11 小时前
Python 调试 Litellm 本地大模型接口:模型列表与对话接口实操踩坑记录
开发语言·python