race condition in the common lock on file?
this is the standard approach to create locks using file system. For example, visudo uses it:
[ -f ".lock" ] && exit 1 touch .lock # do something rm .lock
1) I'm confused, for there's a race condition, yet Linux uses it
2) is there a better way to lock on files from shell?
3) or do I have to use directories instead?
Found solution: man lockfile.
Yes, there is indeed a race condition in the sample script. You can use bash's noclobber option in order to get a failure in case of a race, when a different script sneaks in between the test and the touch.
It's described here. I've excerpted the critical piece, with a couple of annotations (prefixed by BK:):
A possible solution to this is to use IO redirection and bash's noclobber mode, which won't redirect to an existing file. We can use something similar to:
if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; then # BK: this will cause the lock file to be deleted in case of other exit trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT # critical-section BK: (the protected bit) rm -f "$lockfile" trap - INT TERM EXIT else echo "Failed to acquire lockfile: $lockfile." echo "Held by $(cat $lockfile)" fi