如何在shell脚本中实现单例
How to implement singleton in shell script
在 kornshell 中,`basename $0` 为我提供了当前脚本的名称。
我如何利用 $$ 或 $PPID 来实现仅让任何用户在此服务器上执行一个名为 `basename $0` 的脚本的单例模式?
ps -ef|grep `basename [=11=]`
这将向我显示具有当前 运行 脚本名称的所有 运行 进程。
我需要一个脚本,它可以在非 $$ 的线程是 运行 名为 `basename $0` 的脚本时中止。
要提供无竞争互斥体,flock
是你的朋友。如果您不在 Linux - provided by util-linux -- a portable version 可用。
如果您真的希望它应用于整个系统——跨用户帐户——您将需要一个目录来存放您的锁,所有用户都可以在其中创建文件,并且您需要确保所有用户可以写入您的锁定文件。
假设您有 flock
实用程序,每个想要参与此协议的程序都可以按如下方式运行:
#!/bin/ksh
umask 000 # allow all users to access the file we're about to create
exec 9>"/tmp/${0##*/}.lck" # open lockfile on FD 9, based on basename of argv[0]
umask 022 # move back to more restrictive file permissions
flock -x -n 9 || exit # grab that lock, or exit the script early
# continue
一个关键提示:不要在脚本退出时尝试删除锁定文件。如果您处于其他人正在积极尝试获取锁的情况下,他们将已经在该现有文件上拥有文件描述符;如果你在文件有句柄的时候删除文件,你只是确保了一个竞争,其中该程序可以认为它持有锁,而其他人以相同的名称创建一个新文件并锁定它。
在 kornshell 中,`basename $0` 为我提供了当前脚本的名称。
我如何利用 $$ 或 $PPID 来实现仅让任何用户在此服务器上执行一个名为 `basename $0` 的脚本的单例模式?
ps -ef|grep `basename [=11=]`
这将向我显示具有当前 运行 脚本名称的所有 运行 进程。
我需要一个脚本,它可以在非 $$ 的线程是 运行 名为 `basename $0` 的脚本时中止。
要提供无竞争互斥体,flock
是你的朋友。如果您不在 Linux - provided by util-linux -- a portable version 可用。
如果您真的希望它应用于整个系统——跨用户帐户——您将需要一个目录来存放您的锁,所有用户都可以在其中创建文件,并且您需要确保所有用户可以写入您的锁定文件。
假设您有 flock
实用程序,每个想要参与此协议的程序都可以按如下方式运行:
#!/bin/ksh
umask 000 # allow all users to access the file we're about to create
exec 9>"/tmp/${0##*/}.lck" # open lockfile on FD 9, based on basename of argv[0]
umask 022 # move back to more restrictive file permissions
flock -x -n 9 || exit # grab that lock, or exit the script early
# continue
一个关键提示:不要在脚本退出时尝试删除锁定文件。如果您处于其他人正在积极尝试获取锁的情况下,他们将已经在该现有文件上拥有文件描述符;如果你在文件有句柄的时候删除文件,你只是确保了一个竞争,其中该程序可以认为它持有锁,而其他人以相同的名称创建一个新文件并锁定它。