Bash one-liner to atomically create a file if it doesn't exist
I want a Bash one-liner that atomically creates a file if it doesn't exist. That means essentially "if file doesn't exist, create it" but ensuring that no one else manages to create the file in the small space between doing the if and creating the file.
Solution 1:
Stealing an answer from various comments and links to [SO]. It seems there is a POSIX compliant method that doesn't involve mkdir
as I mentioned in my original answer below
set -o noclobber # or set -C
{ > file ; } &> /dev/null
This redirect to file returns 0 or fails and returns non-zero if the file already exists.
Original answer
You'll have to use mkdir
- that's atomic, either the directory gets created and you can continue or it doesn't created so you take appropriate action.
Of course, mkdir
doesn't create a file but once you know you have exclusive access to the directory then you can make the file you want in it.
As to a one liner - I'll leave that up to you. Personally I'd write it over a few lines, as that'll be more maintainable.
Solution 2:
Try this one. The ln
provides the test-and-set functionality.
touch lock.$$.tmp
if ln lock.$$.tmp lock.dat 2>/dev/null
then
echo "File is mine"
else
echo "Test and set failed"
fi
rm -f lock.$$.tmp