Bash one-liner pour créer atomiquement un fichier s'il n'existe pas


9

Je veux une ligne unique Bash qui crée atomiquement un fichier s'il n'existe pas. Cela signifie essentiellement "si le fichier n'existe pas, créez-le", mais assurez-vous que personne d'autre ne parvient à créer le fichier dans le petit espace entre faire le si et créer le fichier.


Désolé, j'ai lu «atomiquement» comme «automatiquement». J'ai supprimé ma réponse.
Aaron Copley

Réponses:


6

Voler une réponse à partir de divers commentaires et liens vers [SO]. Il semble qu'il existe une méthode compatible POSIX qui n'implique pas mkdircomme je l'ai mentionné dans ma réponse d'origine ci-dessous

set -o noclobber # or set -C
{ > file ; } &> /dev/null

Cette redirection vers le fichier renvoie 0 ou échoue et retourne non nul si le fichier existe déjà.


Réponse originale

Vous devrez utiliser mkdir- c'est atomique, soit le répertoire est créé et vous pouvez continuer, soit il ne l'est pas, vous prenez donc les mesures appropriées.

Bien sûr, mkdirne crée pas de fichier mais une fois que vous savez que vous avez un accès exclusif au répertoire, vous pouvez y créer le fichier que vous souhaitez.

Quant à un seul paquebot - je m'en remets à vous. Personnellement, je l'écrirais sur quelques lignes, car ce sera plus facile à maintenir.


Mais le noclobber de stackoverflow.com/q/13828544/1207760 est plus ce que souhaite OP.
Loi29

Noclobber est, en général, une bonne réponse. Mais cela ne fonctionne pas pour ksh88.
jrw32982 prend en charge Monica

1
@JohnWiersba mais la question concerne bash.
womble

@womble yes mais la réponse mentionne POSIX que quelqu'un pourrait considérer comme signifiant que la réponse s'applique à d'autres shells. Ksh88 est toujours le shell standard sur certains serveurs.
jrw32982 prend en charge Monica

0

S'agit-il d'un fichier ou d'un répertoire? Si fichier, vous pouvez utiliser une simple commande tactile - si le fichier existe, il suffit de modifier la dernière heure d'accès. Si le fichier n'existe pas, est créé.


0

Essaye celui-là. Le lnfournit la fonctionnalité de test et de configuration.

touch lock.$$.tmp
if ln lock.$$.tmp lock.dat 2>/dev/null
then
    echo "File is mine"
else
    echo "Test and set failed"
fi
rm -f lock.$$.tmp

0

Si vous ne vous souciez pas du nom de fichier, vous pouvez déléguer cette tâche à un utilitaire, par exemple mktemp

Create a temporary file or directory, safely, and print its name.
TEMPLATE must contain at least 3 consecutive `X's in last component.
If TEMPLATE is not spec‐ified, use tmp.XXXXXXXXXX, and --tmpdir is 
implied.  Files are created u+rw, and directories u+rwx, minus umask
restrictions.

Invocation:

filename=$(mktemp)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.