GNU/Linux >> Znalost Linux >  >> Linux

Jaký je nejlepší způsob, jak zajistit, aby byla spuštěna pouze jedna instance skriptu Bash?

Poradenské zamykání se používá po věky a lze jej použít v bash skriptech. Dávám přednost jednoduchému flock (od util-linux[-ng] ) přes lockfile (od procmail ). A vždy pamatujte na past při ukončení (sigspec ==EXIT nebo 0 , zachycení konkrétních signálů je v těchto skriptech nadbytečné.

V roce 2009 jsem vydal svůj uzamykatelný scénář skriptu (původně dostupný na mé wiki stránce, dnes dostupný jako hlavní). Převést to na jednu instanci na uživatele je triviální. Pomocí něj můžete také snadno psát skripty pro jiné scénáře vyžadující určité zamykání nebo synchronizaci.

Zde je zmíněný popis pro vaše pohodlí.

#!/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.

Pokud je skript pro všechny uživatele stejný, můžete použít lockfile přístup. Pokud získáte zámek, pokračujte, jinak zobrazte zprávu a ukončete.

Jako příklad:

[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] $ 

Po /tmp/the.lock byl získán, váš skript bude jediný s přístupem ke spuštění. Až budete hotovi, stačí odstranit zámek. Ve formě skriptu to může vypadat takto:

#!/bin/bash

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

# Do stuff here

rm -f /tmp/the.lock

Myslím, že flock je pravděpodobně nejjednodušší (a zapamatovatelná) varianta. Používám ho v úloze cron k automatickému kódování DVD a CD

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

Použijte -w pro časové limity nebo vynechejte možnosti a počkejte, dokud se zámek neuvolní. Nakonec manuálová stránka ukazuje pěkný příklad pro více příkazů:

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

Linux
  1. Nejlepší způsob, jak zjistit (ze skriptu), zda je software nainstalován?

  2. „Správný“ způsob, jak otestovat, zda služba běží ve skriptu?

  3. Jak se ujistit, že běží pouze jedna instance Bash skriptu?

  1. Nejlepší způsob, jak zajistit, aby se skript spouštěl jednou za období?

  2. Jaký je nejlepší způsob, jak vyslat signál všem členům procesní skupiny?

  3. Jaké je použití $# v Bash

  1. Jaký je rozdíl mezi prováděním skriptu Bash a jeho získáváním?

  2. Právě jsem smazal /bin. Jaký je nejlepší způsob, jak se zotavit?

  3. Jaký je nejlepší způsob, jak znovu spojit soubory po jejich rozdělení?