侧边栏壁纸
博主头像
liveJQ博主等级

沒有乐趣,何来开始

  • 累计撰写 171 篇文章
  • 累计创建 67 个标签
  • 累计收到 2 条评论

给 Shell 脚本加锁

liveJQ
2024-11-01 / 0 评论 / 0 点赞 / 41 阅读 / 1,004 字

目前的需求是想跑一个定时脚本,定时每两分钟检查一次目录,一旦有新增目录,则把新增目录复制到目标文件夹。但是新增的目录至少都会有几个GB,复制的过程可能会很久,定时的两分钟肯定会再次自动执行的,这可咋办呢,这时候就需要用到锁了。

使用 flock

简单高效,但是需要系统支持。

测试脚本:

#!/bin/bash

LOCKFILE="/tmp/monitor_and_copy.lock"

# 打开一个文件描述符 200,并将它指向文件 $LOCKFILE,实现对该文件的独占访问
exec 200>$LOCKFILE

# 尝试加锁,如果失败则退出
flock -n 200 || { echo "Script is already running. Exiting."; exit 1; }

# 正常的脚本逻辑
echo "Script started at $(date)"
# 模拟脚本运行时间
sleep 30
echo "Script completed at $(date)"

尝试打开两个会话窗口运行这个脚本,同一时间只有一个窗口可以运行该脚本。

使用 PID 文件

兼容性好,但使用较繁琐。

测试脚本:

#!/bin/bash

LOCKFILE="/tmp/monitor_and_copy.pid"

# 检查锁文件是否存在
if [ -f "$LOCKFILE" ]; then
  # 检查进程是否仍在运行
  if kill -0 $(cat "$LOCKFILE") 2>/dev/null; then
    echo "Script is already running. Exiting."
    exit 1
  else
    # 如果进程不在,清除过期的锁文件
    echo "Stale lock file found. Cleaning up."
    rm -f "$LOCKFILE"
  fi
fi

# 创建锁文件,写入当前进程 ID
echo $$ > "$LOCKFILE"

# 设置退出时清理锁文件
trap "rm -f $LOCKFILE" EXIT

# 正常的脚本逻辑
echo "Script started at $(date)"
# 模拟脚本运行时间
sleep 30
echo "Script completed at $(date)"
0

评论区