Bash one-liner para crear atómicamente un archivo si no existe


9

Quiero un Bash one-liner que crea atómicamente un archivo si no existe. Eso significa esencialmente "si el archivo no existe, créelo", pero asegurando que nadie más logre crear el archivo en el pequeño espacio entre hacer el if y crear el archivo.


Lo siento, leí 'atómicamente' como 'automáticamente'. Borré mi respuesta.
Aaron Copley

Respuestas:


6

Robar una respuesta de varios comentarios y enlaces a [SO]. Parece que hay un método compatible con POSIX que no involucra mkdircomo mencioné en mi respuesta original a continuación

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

Esta redirección al archivo devuelve 0 o falla y devuelve un valor distinto de cero si el archivo ya existe.


Respuesta original

Tendrá que usar mkdir: eso es atómico, o el directorio se crea y puede continuar o no se crea, por lo que debe tomar las medidas adecuadas.

Por supuesto, mkdirno crea un archivo, pero una vez que sabe que tiene acceso exclusivo al directorio, puede crear el archivo que desee.

En cuanto a un trazador de líneas, te lo dejaré a ti. Personalmente lo escribiría en unas pocas líneas, ya que será más fácil de mantener.


Pero noclobber de stackoverflow.com/q/13828544/1207760 es más lo que quiere OP.
Ley 29 de

Noclobber es, en general, una buena respuesta. Pero no funciona para ksh88.
jrw32982 apoya a Monica

1
@JohnWiersba, pero la pregunta es sobre bash.
womble

@womble sí, pero la respuesta menciona POSIX que alguien podría tomar para significar que la respuesta se aplica a otros shells. Ksh88 sigue siendo el shell estándar en algunos servidores.
jrw32982 es compatible con Monica el

0

¿Es un archivo o directorio? Si es un archivo, puede usar el comando táctil simple: si el archivo existe, simplemente modifica el último tiempo de acceso. Si el archivo no existe, se crea.


0

Prueba este. El lnproporciona la funcionalidad de prueba y configuración.

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 no le importa el nombre del archivo, puede delegar esta tarea a una utilidad, por ejemplo 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.

Invocación:

filename=$(mktemp)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.