What's a quick-and-dirty way to make sure that only one instance of a shell script is running at a given time?
相关问题
- How to get the return code of a shell script in lu
- JQ: Select when attribute value exists in a bash a
- Invoking Mirth Connect CLI with Powershell script
- Emacs shell: save commit message
- bash print whole line after splitting line with if
相关文章
- 使用2台跳板机的情况下如何使用scp传文件
- In IntelliJ IDEA, how can I create a key binding t
- Check if directory exists on remote machine with s
- shell中反引号 `` 赋值变量问题
- How get the time in milliseconds in FreeBSD?
- Reverse four length of letters with sed in unix
- Launch interactive SSH bash session from PHP
- BASH: Basic if then and variable assignment
Take a look to FLOM (Free LOck Manager) http://sourceforge.net/projects/flom/: you can synchronize commands and/or scripts using abstract resources that does not need lock files in a filesystem. You can synchronize commands running in different systems without a NAS (Network Attached Storage) like an NFS (Network File System) server.
Using the simplest use case, serializing "command1" and "command2" may be as easy as executing:
and
from two different shell scripts.
All approaches that test the existence of "lock files" are flawed.
Why? Because there is no way to check whether a file exists and create it in a single atomic action. Because of this; there is a race condition that WILL make your attempts at mutual exclusion break.
Instead, you need to use
mkdir
.mkdir
creates a directory if it doesn't exist yet, and if it does, it sets an exit code. More importantly, it does all this in a single atomic action making it perfect for this scenario.For all details, see the excellent BashFAQ: http://mywiki.wooledge.org/BashFAQ/045
If you want to take care of stale locks, fuser(1) comes in handy. The only downside here is that the operation takes about a second, so it isn't instant.
Here's a function I wrote once that solves the problem using fuser:
You can use it in a script like so:
If you don't care about portability (these solutions should work on pretty much any UNIX box), Linux' fuser(1) offers some additional options and there is also flock(1).
PID and lockfiles are definitely the most reliable. When you attempt to run the program, it can check for the lockfile which and if it exists, it can use
ps
to see if the process is still running. If it's not, the script can start, updating the PID in the lockfile to its own.Actually although the answer of bmdhacks is almost good, there is a slight chance the second script to run after first checked the lockfile and before it wrote it. So they both will write the lock file and they will both be running. Here is how to make it work for sure:
The
noclobber
option will make sure that redirect command will fail if file already exists. So the redirect command is actually atomic - you write and check the file with one command. You don't need to remove the lockfile at the end of file - it'll be removed by the trap. I hope this helps to people that will read it later.P.S. I didn't see that Mikel already answered the question correctly, although he didn't include the trap command to reduce the chance the lock file will be left over after stopping the script with Ctrl-C for example. So this is the complete solution
Really quick and really dirty? This one-liner on the top of your script will work:
Of course, just make sure that your script name is unique. :)
This example is explained in the man flock, but it needs some impovements, because we should manage bugs and exit codes:
You can use another method, list processes that I used in the past. But this is more complicated that method above. You should list processes by ps, filter by its name, additional filter grep -v grep for remove parasite nad finally count it by grep -c . and compare with number. Its complicated and uncertain