Bash one-liner per creare atomicamente un file se non esiste


9

Voglio un Bash one-liner che crea atomicamente un file se non esiste. Ciò significa essenzialmente "se il file non esiste, crearlo", ma garantire che nessun altro riesca a creare il file nel piccolo spazio tra fare l'if e creare il file.


Mi dispiace, ho letto "atomicamente" come "automaticamente". Ho cancellato la mia risposta.
Aaron Copley,

Risposte:


6

Rubare una risposta da vari commenti e collegamenti a [SO]. Sembra che esista un metodo conforme a POSIX che non comporta mkdircome ho menzionato nella mia risposta originale di seguito

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

Questo reindirizzamento al file restituisce 0 o non riesce e restituisce un valore diverso da zero se il file esiste già.


Risposta originale

Dovrai usare mkdir: è atomico, o la directory viene creata e puoi continuare o non viene creata, quindi intraprendi le azioni appropriate.

Naturalmente, mkdirnon crea un file, ma una volta che sai di avere accesso esclusivo alla directory, puoi creare il file desiderato.

Per quanto riguarda una fodera - lo lascerò a te. Personalmente lo scriverei su poche righe, in quanto sarà più mantenibile.


Ma noclobber da stackoverflow.com/q/13828544/1207760 è più ciò che vuole OP.
Legge

Noclobber è, in generale, una buona risposta. Ma non funziona per ksh88.
jrw32982 supporta Monica

1
@JohnWiersba ma la domanda riguarda bash.
womble

@womble yes, ma la risposta menziona POSIX che qualcuno potrebbe prendere per indicare che la risposta si applica ad altre shell. Ksh88 è ancora la shell standard su alcuni server.
jrw32982 supporta Monica il

0

È un file o una directory? Se il file, è possibile utilizzare un semplice tocco di comando: se il file esiste, modifica solo l'ora dell'ultimo accesso. Se il file non esiste, viene creato.


0

Prova questo. Il lnfornisce la funzionalità di test-and-set.

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

Se non ti interessa il nome del file, puoi delegare questa attività a un'utilità, ad esempio 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.

Invocazione:

filename=$(mktemp)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.