确保在 Linux 上仅运行一个 Bash 脚本实例
简介
在 Linux 上运行bash脚本时,务必确保一次只运行一个脚本实例。这对于执行关键任务的脚本尤其重要,例如更新数据库或发送电子邮件的脚本。同时运行多个相同脚本实例可能会导致冲突、数据丢失和其他错误。在本文中,我们将讨论确保 Linux 上仅运行一个bash脚本实例的不同方法。
使用 Flock
确保 Linux 上仅运行一个bash脚本实例的一种方法是使用“flock”命令。flock命令用于对文件创建锁,并且是大多数 shell(例如Bash、Zsh等)中内置的命令。这是一种简单有效的方法,可以确保一次只运行一个脚本实例。
我们可以信任这种方法,因为它不会出现竞争条件。此外,当进程完成时,文件上的所有锁都会被释放。这些优点使得 flock 成为确保仅运行一个实例的安全方法。另一个好处是 flock 程序是 flock 系统调用的实现。
flock默认情况下会阻塞,直到锁被释放,然后继续执行,不会出现错误。我们可以使用“-n”参数以非阻塞方式使用 flock。如果文件上存在另一个锁,这将导致 flock 立即以错误退出。
我们可以使用 flock 运行外部脚本或在脚本内部使用它。
运行外部脚本
我们可以像这样在脚本中使用flock:
$ flock -n /var/lock/dobackup.lock ./dobackup.sh
现在假设我们的脚本正在运行。让我们看看如果我们再次执行上一行会发生什么:
$ flock --verbose -n /var/lock/dobackup.lock ./dobackup.sh flock: failed to get lock $ echo $? 1
我们可以看到 flock 通知我们它无法获取锁并以值1(错误)退出。这意味着另一个实例拥有锁。
当flock失败时,它不会运行脚本参数,这可以防止运行多个“dobackup.sh”实例。
在脚本中使用 Flock
我们可以像这样在脚本内部使用flock:
#!/bin/bash
another_instance()
{
echo "There is another instance running, exiting"
exit 1
}
( flock -n 100 || another_instance DEST=/home/backup/`date +%s` mkdir -p "$DEST" rsync -avz root@host:/home/web "$DEST/." ) 100>/var/lock/dobackup.lock
在这种情况下,我们使用文件描述符调用 flock,并将我们需要保护的所有内容括在方括号(子 shell)中,并将其重定向到我们用作锁的文件。我们使用在重定向中使用的文件描述符在开头调用 flock。因此,如果 flock 以错误退出,我们就知道有另一个实例正在运行。
子级别完成后,锁文件将关闭,锁将自动释放。
使用 Pid 文件
确保 Linux 上仅运行一个bash脚本实例的另一种方法是使用pid文件。pid 文件是一个特殊文件,其中包含正在运行的脚本的进程 ID (PID)。通过检查 pid 文件,我们可以确定脚本是否正在运行,如果正在运行,则以错误消息退出脚本。
要实现此方法,我们可以将以下代码添加到脚本的开头:
if [ -f /path/to/pidfile ]; then
pid=$(cat /path/to/pidfile)
if kill -0 $pid 2>/dev/null; then
echo "Script is already running"
exit 1
else
echo $$ > /path/to/pidfile
fi
else
echo $$ > /path/to/pidfile
fi
此代码检查指定路径中是否存在 pid 文件。如果 pid 文件存在,脚本将从文件中读取 pid,并通过向进程发送空信号 (kill -0) 来检查进程是否仍在运行。如果进程仍在运行,脚本将以错误消息退出。如果进程未运行,脚本将用当前进程 ID 覆盖 pid 文件。如果 pid 文件不存在,脚本将创建它并写入当前进程 ID。
在脚本末尾,您可以添加以下代码以删除 pid 文件:
$ rm -f /path/to/pidfile
结论
确保 Linux 上仅运行一个 bash 脚本实例是一项重要任务,可以防止冲突、数据丢失和其他错误。有几种方法可以做到这一点,例如使用 flock 命令使用锁文件,使用 pid 文件,或使用“pgrep”和“kill”命令。每种方法都有其优点和缺点,最适合您的脚本的方法将取决于您的特定需求。通过实现任何这些方法,您可以确保您的脚本顺利运行且不会出错。
数据结构
网络
关系数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP