
Ich möchte mehrere Bash-Shell-Skripte parallel ausführen. Dabei möchte ich jedoch Race Conditions vermeiden. Welche Unix-Befehle sindwirklichAtome, die ich für diesen Zweck verwenden könnte, und wie kann ich sie verwenden?
Antwort1
#!/bin/bash
# Makes sure we exit if flock fails.
set -e
(
# Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
flock -x -w 10 200
# Do stuff
) 200>/var/lock/.myscript.exclusivelock
Dadurch wird sichergestellt, dass Code zwischen "(" und ")" immer nur von einem Prozess ausgeführt wird und dass der Prozess nicht zu lange auf eine Sperre wartet.
Antwort2
Wenn lockfile
es auf Ihrem System nicht installiert ist, mkdir
wird die Arbeit von dann ausgeführt: Es handelt sich um eine atomare Operation, die fehlschlägt, wenn das Verzeichnis bereits vorhanden ist (solange Sie den -p
Befehlszeilenschalter nicht hinzufügen).
create_lock_or_wait () {
path="$1"
wait_time="${2:-10}"
while true; do
if mkdir "${path}.lock.d"; then
break;
fi
sleep $wait_time
done
}
remove_lock () {
path="$1"
rmdir "${path}.lock.d"
}
Antwort3
lockfile(1) scheint ein guter Kandidat zu sein, aber beachten Sie, dass es Teil desprocmailPaket, das Sie möglicherweise noch nicht auf Ihrem Computer installiert haben. Es ist ein so beliebtes Paket, dass es für Ihr System gepackt werden sollte, wenn es noch nicht installiert ist. Drei der vier Systeme, die ich überprüft habe, haben es, und auf dem anderen ist es verfügbar.
Die Anwendung ist einfach:
#!/bin/sh
LOCKFILE=$HOME/.myscript/lock
mkdir -p `dirname $LOCKFILE`
echo Waiting for lock $LOCKFILE...
if lockfile -1 -r15 $LOCKFILE
then
# Do protected stuff here
echo Doing protected stuff...
# Then, afterward, clean up so another instance of this script can run
rm -f $LOCKFILE
else
echo "Failed to acquire lock! lockfile(1) returned $?"
exit 1
fi
Die von mir angegebenen Optionen bewirken, dass der Vorgang bis zu 15 Sekunden lang einmal pro Sekunde wiederholt wird. Lassen Sie das Flag „-r“ weg, wenn der Vorgang ewig dauern soll.
Antwort4
Möglicherweise erledigt der Lockfile-Befehl das Gewünschte.
lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock