Bash one-liner para criar atomicamente um arquivo, se ele não existir


9

Eu quero um one-liner Bash que crie um arquivo atomicamente se ele não existir. Isso significa essencialmente "se o arquivo não existir, crie-o", mas garanta que ninguém mais consiga criar o arquivo no pequeno espaço entre fazer o if e criar o arquivo.


Desculpe, li 'atomicamente' como 'automaticamente'. Eu apaguei minha resposta.
Aaron Copley

Respostas:


6

Roubando uma resposta de vários comentários e links para [SO]. Parece que existe um método compatível com POSIX que não envolve, mkdircomo mencionei na minha resposta original abaixo

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

Esse redirecionamento para o arquivo retorna 0 ou falha e retorna diferente de zero se o arquivo já existir.


Resposta original

Você precisará usar mkdir- isso é atômico, ou o diretório é criado e você pode continuar ou não, para que você tome as medidas apropriadas.

Obviamente, mkdirnão cria um arquivo, mas quando você souber que tem acesso exclusivo ao diretório, poderá criar o arquivo que deseja nele.

Quanto a uma fila - vou deixar isso para você. Pessoalmente, eu o escreveria algumas linhas, pois isso será mais sustentável.


Mas noclobber de stackoverflow.com/q/13828544/1207760 é mais o que o OP quer.
Law29

Noclobber é, em geral, uma boa resposta. Mas isso não funciona para o ksh88.
jrw32982 suporta Monica

1
@ JohnWiersba, mas a pergunta é sobre bash.
womble

@ womble yes, mas a resposta menciona o POSIX, que alguém pode levar para significar que a resposta se aplica a outras conchas. O Ksh88 ainda é o shell padrão em alguns servidores.
Jrw32982 suporta Monica

0

É arquivo ou diretório? Se arquivo, você pode usar o comando simples touch - se o arquivo existir, apenas modifique o horário do último acesso. Se o arquivo não existir, será criado.


0

Tente este. O lnfornece a funcionalidade de teste e configuração.

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 você não se importa com o nome do arquivo, pode delegar esta tarefa a um utilitário, por exemplo 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.

Invocação:

filename=$(mktemp)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.