Linux sleep命令

sleep 是一个简单的Linux/Unix命令,用于在脚本或命令行中暂停执行指定的时间。它通常用于创建延迟、控制执行节奏、轮询等待或避免资源冲突等场景。

注意:sleep命令是Shell脚本编程中最常用的工具之一,它不会消耗CPU资源,只是让当前进程进入睡眠状态。

语法格式

sleep NUMBER[SUFFIX]...
sleep OPTION

可以指定一个或多个时间值,sleep会依次等待每个指定的时间。

命令选项

选项 说明
NUMBER 要暂停的时间数量(默认单位:秒)
SUFFIX 时间单位后缀:s(秒)、m(分)、h(小时)、d(天)
--help 显示帮助信息
--version 显示版本信息

时间单位后缀

后缀 单位 说明
无后缀 默认单位
s seconds
m minutes
h 小时 hours
d days

基本使用示例

示例1:暂停指定秒数

# 暂停5秒
sleep 5

# 暂停1.5秒
sleep 1.5

# 暂停0.5秒(500毫秒)
sleep 0.5

示例2:使用时间单位后缀

# 暂停1分钟
sleep 1m

# 暂停2小时
sleep 2h

# 暂停30分钟
sleep 30m

# 暂停1天
sleep 1d

# 组合使用
sleep 2h 30m 10s  # 暂停2小时30分钟10秒

示例3:在命令行中使用

# 执行命令前暂停
echo "等待3秒后继续..."
sleep 3
echo "继续执行"

# 创建简单的倒计时
for i in {5..1}; do
    echo "$i..."
    sleep 1
done
echo "开始!"

示例4:多个时间参数

# sleep会依次等待每个时间
sleep 1 2 3  # 总共暂停6秒(1+2+3)

# 验证
time sleep 1 2 3
# 输出类似:real 0m6.005s

脚本编程应用

脚本1:简单的进度指示器

#!/bin/bash
# progress_indicator.sh - 进度指示器

echo "开始处理任务..."
echo ""

# 模拟任务处理
for i in {1..10}; do
    echo -n "进度: ["
    for j in $(seq 1 $i); do
        echo -n "#"
    done
    for j in $(seq $i 9); do
        echo -n " "
    done
    echo -n "] $((i*10))%"
    if [ $i -lt 10 ]; then
        echo -ne "\r"
    else
        echo ""
    fi
    sleep 0.5
done

echo ""
echo "任务完成!"

脚本2:网络连接重试

#!/bin/bash
# network_retry.sh - 网络连接重试

MAX_RETRIES=5
RETRY_DELAY=3
URL="http://example.com"

echo "尝试连接到: $URL"
echo "最大重试次数: $MAX_RETRIES"
echo "重试间隔: ${RETRY_DELAY}秒"
echo ""

for ((i=1; i<=MAX_RETRIES; i++)); do
    echo "尝试 $i/$MAX_RETRIES ..."

    # 尝试连接
    if curl --silent --head --fail "$URL" > /dev/null 2>&1; then
        echo "✓ 连接成功!"
        exit 0
    else
        echo "✗ 连接失败"

        if [ $i -lt $MAX_RETRIES ]; then
            echo "等待 ${RETRY_DELAY}秒后重试..."
            sleep $RETRY_DELAY
        fi
    fi
done

echo "错误: 无法连接到 $URL 达到最大重试次数"
exit 1

脚本3:文件监控

#!/bin/bash
# file_monitor.sh - 监控文件变化

FILE_TO_WATCH="/var/log/syslog"
CHECK_INTERVAL=5
LAST_SIZE=0

echo "开始监控文件: $FILE_TO_WATCH"
echo "检查间隔: ${CHECK_INTERVAL}秒"
echo "按 Ctrl+C 停止监控"
echo ""

while true; do
    CURRENT_SIZE=$(stat -c%s "$FILE_TO_WATCH" 2>/dev/null || echo "0")

    if [ "$CURRENT_SIZE" -gt "$LAST_SIZE" ]; then
        NEW_BYTES=$((CURRENT_SIZE - LAST_SIZE))
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 文件新增 ${NEW_BYTES} 字节"

        # 显示新增内容
        if [ $NEW_BYTES -gt 0 ]; then
            tail -c $NEW_BYTES "$FILE_TO_WATCH"
            echo ""
        fi

        LAST_SIZE=$CURRENT_SIZE
    fi

    sleep $CHECK_INTERVAL
done

脚本4:定时任务模拟

#!/bin/bash
# scheduled_task.sh - 定时任务模拟

echo "开始定时任务调度"
echo "任务间隔: 10分钟"
echo ""

while true; do
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 执行任务..."

    # 模拟任务执行
    echo "  1. 检查系统状态..."
    uptime
    echo "  2. 检查磁盘空间..."
    df -h /
    echo "  3. 检查内存使用..."
    free -h
    echo "  4. 任务完成"
    echo ""

    # 等待10分钟
    echo "等待10分钟..."
    sleep 600
done

高级用法

示例5:子秒级精度

# 支持小数秒
sleep 0.1    # 100毫秒
sleep 0.01   # 10毫秒
sleep 0.001  # 1毫秒

# 注意:实际精度受系统限制
# 在大多数系统上,最小精度约为0.01秒(10毫秒)

示例6:与timeout结合使用

# 设置命令执行超时
timeout 5 sleep 10
echo "退出状态: $?"  # 124表示超时

# 实际应用:限制长时间运行命令
timeout 30 some_long_running_command

示例7:信号处理

#!/bin/bash
# signal_handling.sh - sleep信号处理

# 设置信号处理
trap 'echo "收到中断信号,退出..."; exit' INT TERM

echo "脚本PID: $$"
echo "按 Ctrl+C 中断睡眠"
echo "开始睡眠10秒..."

# sleep会被信号中断
sleep 10

# 检查是否被中断
if [ $? -eq 0 ]; then
    echo "睡眠完成"
else
    echo "睡眠被中断"
fi

示例8:精确计时

#!/bin/bash
# precise_timing.sh - 精确计时

echo "开始精确计时测试..."
echo ""

# 记录开始时间
start_time=$(date +%s.%N)

# 执行sleep
sleep 2.5

# 记录结束时间
end_time=$(date +%s.%N)

# 计算实际耗时
elapsed_time=$(echo "$end_time - $start_time" | bc)

echo "目标暂停时间: 2.5秒"
echo "实际暂停时间: ${elapsed_time}秒"
echo "误差: $(echo "$elapsed_time - 2.5" | bc)秒"

实际应用场景

场景1:API请求限速

#!/bin/bash
# api_rate_limit.sh - API请求限速

API_URL="https://api.example.com/data"
REQUESTS_PER_MINUTE=60
DELAY=$((60 / REQUESTS_PER_MINUTE))

echo "API限速控制"
echo "目标速率: ${REQUESTS_PER_MINUTE} 请求/分钟"
echo "请求间隔: ${DELAY} 秒"
echo ""

for i in {1..10}; do
    echo "发送请求 $i..."

    # 发送API请求
    response=$(curl -s "$API_URL")

    # 处理响应
    if [ $? -eq 0 ]; then
        echo "  请求成功"
    else
        echo "  请求失败"
    fi

    # 控制请求速率
    if [ $i -lt 10 ]; then
        echo "  等待 ${DELAY}秒..."
        sleep $DELAY
    fi
done

echo "所有请求完成"

场景2:批量处理延迟

#!/bin/bash
# batch_processing.sh - 批量处理延迟

FILES=("file1.txt" "file2.txt" "file3.txt" "file4.txt" "file5.txt")
PROCESS_DELAY=2  # 处理每个文件后暂停2秒

echo "开始批量处理文件"
echo "文件数量: ${#FILES[@]}"
echo "处理间隔: ${PROCESS_DELAY}秒"
echo ""

for file in "${FILES[@]}"; do
    echo "处理文件: $file"

    # 模拟文件处理
    echo "  处理中..."
    sleep 1  # 模拟处理时间

    echo "  处理完成"

    # 处理间隔
    echo "  等待 ${PROCESS_DELAY}秒..."
    sleep $PROCESS_DELAY
    echo ""
done

echo "批量处理完成"

场景3:系统启动等待

#!/bin/bash
# service_wait.sh - 等待服务启动

SERVICE="docker"
MAX_WAIT=60
WAIT_INTERVAL=5

echo "等待 $SERVICE 服务启动..."
echo "最长等待时间: ${MAX_WAIT}秒"
echo "检查间隔: ${WAIT_INTERVAL}秒"
echo ""

elapsed=0
while [ $elapsed -lt $MAX_WAIT ]; do
    if systemctl is-active --quiet "$SERVICE"; then
        echo "✓ $SERVICE 服务已启动"
        exit 0
    fi

    echo "等待 $SERVICE 服务启动... (已等待 ${elapsed}秒)"
    sleep $WAIT_INTERVAL
    elapsed=$((elapsed + WAIT_INTERVAL))
done

echo "错误: $SERVICE 服务在 ${MAX_WAIT}秒内未启动"
exit 1

性能考虑

精度比较

实现方式 精度 资源占用 适用场景
sleep命令 约10毫秒 低(进程睡眠) 一般延迟、脚本暂停
usleep命令 微秒级 高精度延迟(需要安装)
busy loop 纳秒级(理论上) 高(CPU占用100%) 不推荐,仅用于测试
select/poll 微秒级 中等 网络编程、高精度定时

替代命令:usleep

# usleep提供微秒级精度
# 安装(如果需要)
sudo apt-get install usleep

# 使用usleep(微秒为单位)
usleep 1000000  # 暂停1秒(1000000微秒)
usleep 500000   # 暂停0.5秒
usleep 1000     # 暂停1毫秒

故障排除

问题1:sleep命令不存在

sleep: command not found

解决方案:

# sleep通常是Shell内置命令
# 检查类型
type sleep

# 如果是外部命令,尝试重新安装
# Debian/Ubuntu
sudo apt-get install coreutils

# RHEL/CentOS
sudo yum install coreutils

问题2:sleep精度不足

# sleep实际暂停时间与预期不符

解决方案:

# 1. 了解系统限制
# 大多数系统的最小sleep精度约为0.01秒

# 2. 使用usleep获取更高精度
usleep 1000  # 1毫秒

# 3. 使用其他高精度定时方法
# 例如在Python中使用time.sleep()

问题3:sleep被信号中断

# sleep被信号(如Ctrl+C)提前唤醒

解决方案:

#!/bin/bash
# 捕获信号
trap 'echo "忽略中断信号"; continue' INT

echo "开始睡眠,按Ctrl+C不会中断"
sleep 10
echo "睡眠完成"

问题4:浮点数支持

# 某些旧版本sleep不支持小数
sleep 0.5
# 错误: sleep: invalid time interval '0.5'

解决方案:

# 1. 使用整数秒
sleep 1

# 2. 使用usleep
usleep 500000  # 0.5秒

# 3. 使用其他方法实现小数秒
perl -e 'select(undef, undef, undef, 0.5)'

相关命令

命令 说明
usleep 微秒级精度暂停
wait 等待进程完成
timeout 设置命令执行超时
watch 定期执行命令并显示输出
at 在指定时间执行命令
cron 定时执行任务
date 显示和设置系统时间
time 测量命令执行时间

最佳实践

sleep命令使用最佳实践:
  1. 明确单位:始终使用时间单位后缀,提高可读性
  2. 合理间隔:根据实际需要选择适当的暂停时间
  3. 避免忙等待:使用sleep而不是循环检查,减少CPU占用
  4. 信号处理:在脚本中正确处理信号,特别是长时间sleep
  5. 错误检查:检查sleep的退出状态,处理可能的错误
  6. 性能考虑:了解sleep的精度限制,必要时使用高精度替代方案
  7. 可读性:在脚本中添加注释,说明sleep的目的
  8. 可配置:将延迟时间设为变量,便于调整

sleep命令速查表

用途 命令示例
暂停1秒 sleep 1
暂停1分钟 sleep 1m
暂停1小时 sleep 1h
暂停1天 sleep 1d
暂停0.5秒 sleep 0.5
暂停多个时间 sleep 1 2 3
显示帮助 sleep --help
显示版本 sleep --version
在脚本中使用 echo "等待..."; sleep 5; echo "完成"
倒计时 for i in {5..1}; do echo $i; sleep 1; done

与相关命令对比

命令 精度 用途 示例
sleep 秒级(支持小数) 暂停执行指定时间 sleep 2.5
usleep 微秒级 高精度暂停 usleep 100000
wait N/A 等待进程完成 wait $PID
timeout 秒级 限制命令执行时间 timeout 5 command
watch 秒级 定期执行命令 watch -n 1 command

跨平台兼容性

sleep命令在不同系统上的行为:

系统 sleep实现 特性 注意事项
Linux GNU coreutils 支持小数秒、时间单位后缀 标准实现,功能最全
macOS BSD sleep 只支持整数秒,无后缀 功能有限,需使用整数
FreeBSD BSD sleep 支持小数秒 与Linux类似
Solaris 传统Unix sleep 只支持整数秒 功能有限
Windows (WSL) GNU coreutils 与Linux相同 WSL中完全兼容

跨平台兼容的sleep脚本

#!/bin/bash
# cross_platform_sleep.sh - 跨平台兼容的sleep

# 检测系统类型
detect_system() {
    case "$(uname -s)" in
        Linux*)     echo "linux" ;;
        Darwin*)    echo "macos" ;;
        FreeBSD*)   echo "freebsd" ;;
        *)          echo "unknown" ;;
    esac
}

# 跨平台sleep函数
safe_sleep() {
    local seconds=$1
    local system=$(detect_system)

    case "$system" in
        linux|freebsd)
            # Linux和FreeBSD支持小数
            sleep "$seconds"
            ;;
        macos)
            # macOS只支持整数秒
            sleep $((seconds))

            # 如果有小数部分,使用其他方法
            if [[ "$seconds" =~ \. ]]; then
                local int_part=${seconds%.*}
                local frac_part=${seconds#*.}
                # 使用perl处理小数部分
                perl -e "select(undef, undef, undef, 0.$frac_part)"
            fi
            ;;
        *)
            # 默认使用整数秒
            sleep $((seconds))
            ;;
    esac
}

# 使用示例
echo "跨平台sleep演示"
echo "系统: $(detect_system)"
echo ""

echo "暂停2.5秒..."
safe_sleep 2.5
echo "完成"

总结

sleep命令是Shell脚本编程中不可或缺的工具,用于控制执行节奏、创建延迟、避免资源竞争等。虽然简单,但在实际应用中有着广泛的用途。了解其特性、限制和最佳实践,可以帮助编写更健壮、可靠的脚本。

关键点:
  • sleep不会消耗CPU资源,进程进入睡眠状态
  • 支持秒、分、小时、天等单位,提高可读性
  • 实际精度受系统限制,通常约10毫秒
  • 可以被信号中断,需要注意信号处理
  • 在不同系统上有兼容性差异,编写跨平台脚本时需要注意