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

8

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

    
por Ram Rachum 01.05.2016 / 15:11

4 respostas

5

Roubar 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 mkdir como eu mencionado na minha resposta original abaixo

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

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

Resposta original

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

É claro que mkdir não cria um arquivo, mas quando você sabe que tem acesso exclusivo ao diretório, pode criar o arquivo que deseja nele.

Quanto a um forro - eu deixo isso para você. Pessoalmente eu escreveria algumas linhas, pois isso será mais sustentável.

    
por 01.05.2016 / 15:58
0

É arquivo ou diretório? Se o arquivo, você pode usar o simples toque de comando - se o arquivo existe, basta modificar o último acesso. Se o arquivo não existe, é criado.

    
por 01.05.2016 / 16:00
0

Tente este. O ln fornece a funcionalidade de teste e conjunto.

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
    
por 01.05.2016 / 23:09
0

Se você não se importa com o nome do arquivo, você pode delegar essa tarefa para 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)
    
por 05.06.2016 / 21:57

Tags