news 2026/4/23 13:34:02

safe_sleep.sh: GitHub Actions Runner 中那个偶尔无限挂起的“小睡眠”脚本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
safe_sleep.sh: GitHub Actions Runner 中那个偶尔无限挂起的“小睡眠”脚本

在 GitHub Actions Runner 代码库里,有一个看似简单的 Bash 脚本——safe_sleep.sh,它负责让 Runner 在某些场景下“安全地睡眠”一段时间。但这个小脚本却因为一个 subtle 的逻辑缺陷,让许多开发者和 CI 系统管理员困扰不已,甚至引发了性能、资源浪费、Runner 卡死等严重问题。

一、什么是safe_sleep.sh

GitHub Actions Runner 是负责执行 CI/CD 工作流程的后台服务。某些流程中,Runner 需要暂停一段时间(例如等待自动更新完成),这时就会调用一个名为safe_sleep.sh的脚本。

看似是个简单任务:让程序睡眠 N 秒钟。但设计者并没有调用系统自带的sleep命令,而是用 Bash 语言编写了一个自循环脚本。

在旧版本中,脚本内容大致如下:

#!/bin/bash SECONDS=0 while [[ $SECONDS != $1 ]]; do : done

通过 busy-waiting 来实现睡眠,而不是调用标准sleep

二、问题核心:循环条件有 Bug

乍看这段代码好像没毛病,但它有一个细节严重依赖了调度时机

while [[ $SECONDS != $1 ]]; do …

这个循环假设SECONDS会按 0 → 1 → 2 → … 逐秒增加并且正好等于目标值。但在真实环境中:

  • 如果机器负载高;

  • 或者 Runner 进程被系统调度延迟;

  • 或者在虚拟化环境里暂停一段时间;

那么SECONDS有可能会直接跳过目标值,例如从 0 跳到 2。在这种情况下:

条件永远不会变成 “等于目标值”,循环就会永远执行下去 ——无限循环

三、实际观测到的问题

Very rarely on update of github actions runnersafe_sleep.shhangs forever:

$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND ... actions+ 72298 96.3 0.0 4372 3328 ? R Apr02 1988:54 /bin/bash /home/actions-runner/safe_sleep.sh 1 ...

详见:safe_sleep.sh rarely hangs indefinitely

四、影响案例:更多比预想严重

不仅仅是某个挂起的新 Runner,某些开源项目(例如 Zig)据反馈在自托管 Runner 上观察到了成堆的死循环实例,这些无限循环的safe_sleep.sh不仅占满了 CPU,还导致 Runner 服务无法正常运行数日之久。

五、修复版本

https://github.com/actions/runner/commits/main/src/Misc/layoutroot/safe_sleep.sh

1. 最新修复版本
#!/bin/bash # try to use sleep if available if [ -x "$(command -v sleep)" ]; then sleep "$1" exit 0 fi # try to use ping if available if [ -x "$(command -v ping)" ]; then ping -c $(( $1 + 1 )) 127.0.0.1 > /dev/null exit 0 fi # try to use read -t from stdin/stdout/stderr if we are in bash if [ -n "$BASH_VERSION" ]; then if command -v read >/dev/null 2>&1; then if [ -t 0 ]; then read -t "$1" -u 0 || :; exit 0 fi if [ -t 1 ]; then read -t "$1" -u 1 || :; exit 0 fi if [ -t 2 ]; then read -t "$1" -u 2 || :; exit 0 fi fi fi # fallback to a busy wait SECONDS=0 while [[ $SECONDS -lt $1 ]]; do : done
2. 执行逻辑(从“优雅”到“原始”)
(1)首选:sleep
if [ -x "$(command -v sleep)" ]; then sleep "$1" exit 0 fi
  • 检查sleep是否存在且可执行

  • 最准确、最省 CPU

  • 正常系统 99% 会走到这里

(2)备用:ping
if [ -x "$(command -v ping)" ]; then ping -c $(( $1 + 1 )) 127.0.0.1 > /dev/null exit 0 fi

原理:

  • ping默认每秒发一次

  • N+1个包 ≈ 等N

⚠️ 注意点:

  • 依赖ping没被禁用(某些容器里 ping 被移除或需要 CAP_NET_RAW)

  • 时间精度不如 sleep

  • 127.0.0.1保证不会阻塞网络

(3)再退一步:read -t(仅 Bash)
if [ -n "$BASH_VERSION" ]; then if command -v read >/dev/null 2>&1; then ... fi fi

原理

  • read -t N阻塞 N 秒等待输入

  • 没输入就超时返回

为什么检查-t 0 / 1 / 2

if [ -t 0 ]; then read -t "$1" -u 0; fi
  • read -t必须绑定到 TTY

  • stdin/stdout/stderr 只要有一个是 TTY 就能用

  • 非交互 shell(CI、cron)通常都不是 TTY

(4)最终兜底:busy wait(CPU 自旋)
SECONDS=0 while [[ $SECONDS -lt $1 ]]; do : done
  • SECONDS是 Bash 内建变量(秒级)

  • :是 no-op

  • 100% 占用一个 CPU 核心

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:29:43

Stable Diffusion WebUI Forge:PyTorch驱动的AI绘画革命

Stable Diffusion WebUI Forge:PyTorch驱动的AI绘画革命 【免费下载链接】stable-diffusion-webui-forge 项目地址: https://gitcode.com/GitHub_Trending/st/stable-diffusion-webui-forge 还在为AI绘画工具的性能瓶颈和兼容性问题头疼吗?&…

作者头像 李华
网站建设 2026/4/17 16:07:44

Kindle Comic Converter:漫画电子书格式转换的终极解决方案

Kindle Comic Converter:漫画电子书格式转换的终极解决方案 【免费下载链接】kcc KCC (a.k.a. Kindle Comic Converter) is a comic and manga converter for ebook readers. 项目地址: https://gitcode.com/gh_mirrors/kc/kcc 在数字阅读时代,漫…

作者头像 李华
网站建设 2026/4/18 7:21:44

虚拟偶像背后的语音黑科技——EmotiVoice深度解析

虚拟偶像背后的语音黑科技——EmotiVoice深度解析 在虚拟主播直播带货、数字人客服24小时在线、AI歌手发布新单曲的今天,你有没有想过:这些“非人类”的角色,为何能说出如此自然、富有情绪波动的话语?它们的声音是预先录制的吗&am…

作者头像 李华
网站建设 2026/4/20 4:15:23

如何申请内网国密IP证书?国密内网IP的使用范围包括哪些?

国密IP证书申请流程申请国密内网IP证书需遵循以下步骤:选择证书机构:通过国家密码管理局认证的CA机构(如JoySSL)提交申请(注册填写注册码230959,赠送国密浏览器)生成密钥对:使用国密…

作者头像 李华
网站建设 2026/4/23 13:15:19

9 个降AI率工具,MBA 必备高效降AIGC指南

9 个降AI率工具,MBA 必备高效降AIGC指南 AI降重工具:MBA论文的高效助手 在当今学术研究中,随着人工智能技术的广泛应用,论文中的AIGC率问题逐渐成为MBA学生关注的焦点。许多MBA学员在撰写论文时,常常依赖AI生成内容以提…

作者头像 李华