0

I have a script that creates a temporary file as a flag to guard against the script being run simultaneously. Currently it uses tempfile, e.g.

if ! tempfile -n /tmp/updating > /dev/null; then
    echo 'Another synchronization is currently running' >&2
    exit 1
fi

The tempfile program is now deprecated, it suggests using mktemp instead, but mktemp doesn't seem to have an option similar to -n.

I'm using Ubuntu 21.04.

So how should I safely create a flag file?

  • 1
    If you want to do this specifically with flag files, is touch an option? – Peregrino69 Sep 26 '21 at 08:52
  • What is the -n option supposed to do? I've never heard of tempfile before and have been using mktemp for many years. It seems, from an old man page I found online, that -n just gives a specific name for the "temp" file which seems very odd: if you already know the name, why would you need tempfile to create it? Why not just make your own lockfile name like /tmp/thisisalongfilenamethatonlymyprogramnamedbestprogramwoulduse? – terdon Sep 26 '21 at 09:03
  • 2
    Also - http://mywiki.wooledge.org/BashFAQ/045 – Inian Sep 26 '21 at 09:23
  • @terdon "if you already know the name, bla bla" because you want to open it with O_EXCL? How can you do that from the shell? –  Sep 26 '21 at 09:38
  • Someone suggested flock in a comment, then deleted it. But it works for me. – Steve Piner Sep 26 '21 at 09:39
  • @UncleBilly sorry, my ignorance requires more information. I'm afraid I don't even know what O_EXCL is. My point is that if you don't need a tool like mktemp that will create a unique, random name and instead you already know the name you'll be using, all you need is if [[ -e $file ]]. – terdon Sep 26 '21 at 09:39
  • @terdon - it's to avoid the race condition between checking that the file doesn't exist and creating it. It's probably over-engineering for my purpose, but I think it's good practice. – Steve Piner Sep 26 '21 at 09:41
  • @inian - that's a good resource. I'm (now) using the "flock file descriptor uniqueness" version as described in the flock man page. – Steve Piner Sep 26 '21 at 09:44
  • @Peregrino69 - I don't understand how I would use touch for this. Could you please explain further? – Steve Piner Sep 26 '21 at 09:53
  • @StevePiner - since you've resolved your issue, please don't hesitate to answer it and accept your answer. You might need to wait for a time before you can accept it, but it's a good practice as it'll mark your question as containing solution for others down the line, and lift it off the Unanaswered -queue. Please do describe also how you're using flock. – Peregrino69 Sep 26 '21 at 09:53
  • @StevePiner Basically I was suggesting similar approach to terdon's, creating your own lock file with a chosen name. It's what I usually do and my script's behavior depends on the existence of the file. But as you've resolved this, it's a bit of a moot point :-) – Peregrino69 Sep 26 '21 at 09:56

1 Answers1

0

Someone suggested flock in a comment, then deleted it. While using flock doesn't exactly answer the question as asked (the file is not safely created), it is sufficient for my need (as the lock does prevent the critical section of the script from being run several times simultaneously)

The code above has been changed as follows: it now opens a file descriptor to the /tmp/updating file then locks the open file descriptor.

exec 4<>/tmp/updating
if ! flock --nonblock --exclusive 4; then
    echo 'Another synchronization is currently running' >&2
    exit 1
fi

At the end of the script to release the lock was a rm /tmp/updating. I no longer need to do that as the flock will automatically be released when the script exits.

The man page for flock(1) has some examples for use in different scenarios, I've used the last one.