GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was ist der beste Weg, um sicherzustellen, dass nur eine Instanz eines Bash-Skripts ausgeführt wird?

Advisory Locking wird seit Ewigkeiten verwendet und kann in Bash-Skripten verwendet werden. Ich bevorzuge einfache flock (ab util-linux[-ng] ) über lockfile (ab procmail ). Und denken Sie immer an eine Falle beim Beenden (sigspec ==EXIT oder 0 , das Abfangen spezifischer Signale ist überflüssig) in diesen Skripten.

Im Jahr 2009 veröffentlichte ich meine abschließbare Skript-Boilerplate (ursprünglich auf meiner Wiki-Seite verfügbar, heute als Gist verfügbar). Das Umwandeln in eine Instanz pro Benutzer ist trivial. Mit ihm können Sie auch problemlos Skripte für andere Szenarien schreiben, die eine gewisse Sperrung oder Synchronisierung erfordern.

Hier ist der erwähnte Textbaustein für Ihre Bequemlichkeit.

#!/bin/bash
# SPDX-License-Identifier: MIT

## Copyright (C) 2009 Przemyslaw Pawelczyk <[email protected]>
##
## This script is licensed under the terms of the MIT license.
## https://opensource.org/licenses/MIT
#
# Lockable script boilerplate

### HEADER ###

LOCKFILE="/var/lock/`basename $0`"
LOCKFD=99

# PRIVATE
_lock()             { flock -$1 $LOCKFD; }
_no_more_locking()  { _lock u; _lock xn && rm -f $LOCKFILE; }
_prepare_locking()  { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }

# ON START
_prepare_locking

# PUBLIC
exlock_now()        { _lock xn; }  # obtain an exclusive lock immediately or fail
exlock()            { _lock x; }   # obtain an exclusive lock
shlock()            { _lock s; }   # obtain a shared lock
unlock()            { _lock u; }   # drop a lock

### BEGIN OF SCRIPT ###

# Simplest example is avoiding running multiple instances of script.
exlock_now || exit 1

# Remember! Lock file is removed when one of the scripts exits and it is
#           the only script holding the lock or lock is not acquired at all.

Wenn das Skript für alle Benutzer gleich ist, können Sie einen lockfile verwenden sich nähern. Wenn Sie die Sperre erhalten haben, fahren Sie fort, sonst zeigen Sie eine Nachricht und beenden Sie.

Als Beispiel:

[Terminal #1] $ lockfile -r 0 /tmp/the.lock
[Terminal #1] $ 

[Terminal #2] $ lockfile -r 0 /tmp/the.lock
[Terminal #2] lockfile: Sorry, giving up on "/tmp/the.lock"

[Terminal #1] $ rm -f /tmp/the.lock
[Terminal #1] $ 

[Terminal #2] $ lockfile -r 0 /tmp/the.lock
[Terminal #2] $ 

Nach /tmp/the.lock erworben wurde, ist Ihr Skript das einzige mit Zugriff auf die Ausführung. Wenn Sie fertig sind, entfernen Sie einfach die Sperre. In Skriptform könnte dies so aussehen:

#!/bin/bash

lockfile -r 0 /tmp/the.lock || exit 1

# Do stuff here

rm -f /tmp/the.lock

Ich denke flock ist wohl die einfachste (und einprägsamste) Variante. Ich verwende es in einem Cron-Job, um DVDs und CDs automatisch zu codieren

# try to run a command, but fail immediately if it's already running
flock -n /var/lock/myjob.lock   my_bash_command

Verwenden Sie -w für Timeouts oder Auslassungsoptionen, um zu warten, bis die Sperre aufgehoben wird. Schließlich zeigt die Manpage ein nettes Beispiel für mehrere Befehle:

   (
     flock -n 9 || exit 1
     # ... commands executed under lock ...
   ) 9>/var/lock/mylockfile

Linux
  1. Der beste Weg, um (aus einem Skript) zu erkennen, ob Software installiert ist?

  2. Was ist der beste Weg, um ein Signal an alle Mitglieder einer Prozessgruppe zu senden?

  3. Jede Möglichkeit, das Bash-Skript zu beenden, aber das Terminal nicht zu verlassen

  4. Was ist der beste Weg, um mit Speichermangel in Java umzugehen?

  5. Was ist die Verwendung von $ # in Bash

Wie stelle ich sicher, dass jeweils nur eine Instanz eines Ruby-Skripts ausgeführt wird?

Beschränken Sie ein GUI-Programm in Linux auf nur eine Instanz

Ist es möglich, den Inhalt eines laufenden Bash-Skripts aus dem RAM abzurufen?

Was ist der schnellste Weg, um ein Skript auszuführen?

Was ist der beste Weg, um eine Umgebungsvariable in .bashrc festzulegen?

Was ist der beste Weg, um zu überprüfen, ob ein Volume in einem Bash-Skript gemountet ist?