web-dev-qa-db-fra.com

Y a-t-il un mécanisme mutex / sémaphore dans les scripts Shell?

Je recherche un mécanisme mutex/sémaphore/concurrence dans le script shell. Examinez la situation suivante: à moins que "un utilisateur" ne ferme pas le fichier partagé, l'utilisateur "B" ne doit pas ne pas pouvoir l'ouvrir/le mettre à jour. Je me demande simplement comment implémenter mutex, sémaphore, sections critiques, etc. dans les scripts shell.

Quel est le moyen le plus simple d'implémenter un mécanisme de verrouillage [niveau de fichier] dans des scripts shell?

27
Mandar Pande

Voir Bashfaq et processanagment pour des discussions sur le verrouillage du fichier en bash.

Marquez votre question comme Shell (seulement) limite le nombre de personnes pouvant vous aider. Vous voudrez peut-être ajouter UNIX, KSH, BASH.

Il y a de nombreuses questions/réponses sur ce sujet posté ici déjà sur S.O.

J'espère que ça aide.

13
shellter

Le Bashfaq noté par Cochette a de bons exemples. L'idée de base, que je déplace ici afin que la page soit autonome, consiste à utiliser une opération à la fois teste et ensembles à la fois: MKDIR

mKDIR échouera si le répertoire existe et le fera si ce n'est pas le cas. C'est une opération atomique et vous pouvez l'utiliser comme pour faire un mutex dans votre script shell (de ce qui précède Bashfaq)

# Bourne
lockdir=/tmp/myscript.lock
if mkdir "$lockdir"
then    # directory did not exist, but was created successfully
    echo >&2 "successfully acquired lock: $lockdir"
    # continue script
else    # failed to create the directory, presumably because it already exists
  echo >&2 "cannot acquire lock, giving up on $lockdir"
  exit 0
fi

suivez le lien pour plus de détails sur le nettoyage et d'autres éléments.

39
Paul Rubel

Vous pouvez utiliser l'utilitaire flock pour verrouiller un fichier/l'utiliser comme un mutex.

Exemple:

#!/bin/sh -eu
#advanced bash stuff not needed
: >> lock #create a file if it doesn't exist
{
flock 3 #lock file by filedescriptor

echo $$ working with lock
sleep 2
echo $$ done with lock

} 3<lock

Exemple d'utilisation:

./mx & ./mx & ./mx & #will run one at a time cuz of the lock

(

En réponse à Massimo Pointe:

Si vous ne voulez pas coder un numéro de fichier filé (il devrait rarement être un problème si vous ne connaissez pas 0, 1 ou 2, mais de toute façon), puis en bash (mais pas dans une coque de POSIX uniquement), vous pouvez avoir Le système choisit une FD pour vous avec:

{
flock $fd
#...
} {fd}<lock

)

6
PSkocik