handle race condition
authorIan Kelling <iank@fsf.org>
Thu, 10 Nov 2022 19:46:04 +0000 (14:46 -0500)
committerIan Kelling <iank@fsf.org>
Thu, 10 Nov 2022 19:46:04 +0000 (14:46 -0500)
log-once

index 3aa3c766642b531f812d4d8d08486079497d936a..3532110fc1de9d2b6c2a4e9b5805fc234a5e9ef8 100755 (executable)
--- a/log-once
+++ b/log-once
@@ -6,7 +6,7 @@ append() {
   cat >> "$1"
 }
 log-once() {
-  local cbase c log line i out file o tmp
+  local cbase c log line i out file o tmp mvout mverr
   cbase=/var/local/cron-errors
   [[ $EUID == 0 ]] || cbase=$HOME/cron-errors
   local help="Usage: some-command-that-outputs-on-error |& log-once [OPTION]... LOG_NAME
@@ -30,6 +30,7 @@ I could imagine a similar command that considers its non-option args to
 be an error, but I haven't written it yet.
 "
   errors=3
+  mverr=0
   while true; do
     if [[ $1 == --help ]]; then
       echo "$help"
@@ -69,7 +70,17 @@ be an error, but I haven't written it yet.
       i="${file#$c}"
       if (( i < errors )); then
         new_file=$c$((i+1))
-        mv $file $new_file
+        mvout=$(mv $file $new_file 2>&1) || mverr=$?
+        if (( mverr )); then
+          if [[ $mvout == *": No such file or directory" ]]; then
+            # We've very likely hit a race condition, where another
+            # log-once did the mv before us.
+            return 0
+          else
+            echo "log-once: error on mv $file $new_file"
+            return $mverr
+          fi
+        fi
         file=$new_file
         if [[ $file == $c$errors ]]; then
           out="tee -a"