Quick-and-dirty way to ensure only one instance of a shell script is running at a time

前端 未结 30 2427
忘掉有多难
忘掉有多难 2020-11-22 02:57

What\'s a quick-and-dirty way to make sure that only one instance of a shell script is running at a given time?

30条回答
  •  梦如初夏
    2020-11-22 03:06

    To make locking reliable you need an atomic operation. Many of the above proposals are not atomic. The proposed lockfile(1) utility looks promising as the man-page mentioned, that its "NFS-resistant". If your OS does not support lockfile(1) and your solution has to work on NFS, you have not many options....

    NFSv2 has two atomic operations:

    • symlink
    • rename

    With NFSv3 the create call is also atomic.

    Directory operations are NOT atomic under NFSv2 and NFSv3 (please refer to the book 'NFS Illustrated' by Brent Callaghan, ISBN 0-201-32570-5; Brent is a NFS-veteran at Sun).

    Knowing this, you can implement spin-locks for files and directories (in shell, not PHP):

    lock current dir:

    while ! ln -s . lock; do :; done
    

    lock a file:

    while ! ln -s ${f} ${f}.lock; do :; done
    

    unlock current dir (assumption, the running process really acquired the lock):

    mv lock deleteme && rm deleteme
    

    unlock a file (assumption, the running process really acquired the lock):

    mv ${f}.lock ${f}.deleteme && rm ${f}.deleteme
    

    Remove is also not atomic, therefore first the rename (which is atomic) and then the remove.

    For the symlink and rename calls, both filenames have to reside on the same filesystem. My proposal: use only simple filenames (no paths) and put file and lock into the same directory.

提交回复
热议问题