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

je cherche le mécanisme mutex / sémaphore / concurrency dans le script shell. Considérons la situation suivante: À moins que l'Utilisateur "a" ne ferme pas le fichier partagé, l'utilisateur "B" ne devrait pas pouvoir l'ouvrir/le mettre à jour. Je me demande juste comment implémenter mutex, sémaphore, sections critiques, etc. dans les scripts shell.

Quelle est la façon la plus facile d'implémenter un mécanisme de verrouillage [niveau du fichier] dans les scripts shell?

23
demandé sur Charles Duffy 2011-07-29 12:01:00

3 réponses

Voir BashFAQ et ProcessManagment pour les discussions sur le verrouillage des fichiers à Bash.

marquer votre question comme shell (seulement) limite le nombre de personnes qui peuvent vous aider. Vous pouvez 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 cela aidera.

11
répondu shellter 2011-07-29 19:12:16

BashFAQ noté par shellter a quelques bons exemples. L'idée de base, que je déplace ici pour que la page soit autonome, est d'utiliser une opération qui teste et fixe en même temps: mkdir

mkdir échouera si le répertoire existe et si elle ne le fait pas. C'est une opération atomique et vous pouvez l'utiliser comme ça pour faire un mutex dans votre script shell (à partir du BashFAQ ci-dessus)

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

37
répondu Paul Rubel 2014-03-19 16:06:22

Vous pouvez utiliser le flock utilitaire pour verrouiller un fichier / 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 ' s point:

si vous ne voulez pas de hardcode un nombre filedecriptor (il devrait être rarement un problème si vous n'êtes pas hardcode 0, 1, ou 2, mais de toute façon), puis en bash (mais pas seulement dans un shell POSIX) vous pouvez assigner le choix d'un fd par le système pour vous avec:

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

)

3
répondu PSkocik 2018-08-13 20:26:59