How to implement singleton in shell script

2020-05-02 03:40发布

问题:

In kornshell, `basename $0` gives me the name of the current script.

How would I exploit $$ or $PPID to implement the singleton pattern of only having one script named `basename $0` executed on this server by any user?

ps -ef|grep `basename $0`

This will show me all processes which are running that have the name of the currently running script.

I need a script which can abort when a thread which is not $$ is running the script named `basename $0`.

回答1:

To provide a race-free mutex, flock is your friend. If you aren't on Linux -- where it's provided by util-linux -- a portable version is available.

If you truly want it to apply to the entire system -- crossing user accounts -- you'll need a directory for your locks to live where all users can create files, and you'll need to ensure that all users can write to your lockfiles.

Assuming you have the flock utility, each program which wants to participate in this protocol can behave as follows:

#!/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

One key note: Do not try to delete lockfiles when your script exits. If you're in a condition where someone else is actively trying to grab a lock, they'll already have a file descriptor on that existing file; if you delete the file while they have a handle on it, you just ensured a race wherein that program can think it holds the lock while someone else creates a new file under the same name and locks it.



标签: shell unix ksh