Puoi crearlo con un nome generato casualmente, quindi rinominarlo (mv -n random desired
) in posizione con il nome desiderato. La ridenominazione fallirà se il file esiste già.
In questo modo:
#!/bin/bash
touch randomFileName
mv -n randomFileName lockFile
if [ -e randomFileName ] ; then
echo "Failed to acquired lock"
else
echo "Acquired lock"
fi
Una soluzione bash pura al 100%:
set -o noclobber
{ > file ; } &> /dev/null
Questo comando crea un file chiamato file
se non esiste un file denominato file
. Se c'è un file chiamato file
, quindi non fare nulla (ma restituire un codice di ritorno diverso da zero).
Pro rispetto al touch
comando:
- Non aggiorna il timestamp se il file esiste già
- Bash integrato al 100%
- Restituisci il codice come previsto:fallisce se
file
esisteva già o sefile
non poteva essere creato; successo sefile
non esisteva ed è stato creato.
Contro:
- è necessario impostare
noclobber
opzione (ma va bene in uno script, se stai attento con i reindirizzamenti, o lo disattivi in seguito).
Immagino che questa soluzione sia davvero la controparte bash del open
chiamata di sistema con O_CREAT | O_EXCL
.
Ecco una funzione bash che usa mv -n
trucco:
function mkatomic() {
f="$(mktemp)"
mv -n "$f" "$1"
if [ -e "$f" ]; then
rm "$f"
echo "ERROR: file exists:" "$1" >&2
return 1
fi
}
Esempi:
$ mkatomic foo
$ wc -c foo
0 foo
$ mkatomic foo
ERROR: file exists: foo