Passa vários comandos para o flock

9
flock -x -w 5 ~/counter.txt 'COUNTER=$(cat ~/counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'

Como eu passaria vários comandos para flock como no exemplo acima?

Tanto quanto eu entendo, flock tem diferentes sinalizadores (-x para exclusivo, -w para o tempo limite), então o arquivo a ser bloqueado e, em seguida, o comando a ser executado. Não tenho certeza de como transmitir dois comandos para essa função (defina a variável com o conteúdo do arquivo bloqueado e, em seguida, incremente esse arquivo).

Meu objetivo aqui é criar um incremento um pouco atômico para um arquivo, bloqueando-o sempre que um script tentar acessar o arquivo counter.txt .

    
por d-_-b 29.12.2013 / 21:05

3 respostas

5

Invoque um shell explicitamente.

flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'

Observe que qualquer variável que você altera é local para essa instância do shell. Por exemplo, a variável COUNTER não será atualizada no script de chamada: você terá que lê-la de volta a partir do arquivo (mas pode ter mudado nesse meio tempo) ou como saída do comando:

new_counter=$(flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) | tee ~/counter.txt')
    
por 29.12.2013 / 21:16
4

Ou você pode agrupar um descritor de arquivo

exec {counterfd}<~/counter.txt
flock -x -w 5 "$counterfd"
COUNTER=$(cat ~/counter.txt)
COUNTER=$(( COUNTER +1 ))
echo "$COUNTER" >~/counter.txt
eval exec "$counterfd<&-"

Isso também tem o benefício de permitir que você use a variável contador diretamente, ao contrário das abordagens baseadas em subshell.

    
por 14.09.2015 / 20:01
1

A ferramenta flock é um pouco difícil de usar e a página de manual é bem pequena. A página man fornece três maneiras de usar a ferramenta:

  • flock [options] <file|directory> <command> [command args]
  • flock [options] <file|directory> -c <command>
  • flock [options] <file descriptor number>

A forma como esta questão é formulada, eu definitivamente usaria a terceira forma de flock . Se você for mais abaixo na man page para flock , há alguns exemplos que mostram a sintaxe exata para usar o terceiro formulário:

#!/bin/bash
(
 flock -n 9 || exit 1
 echo "commands executed under lock..."
 echo "go here..."
) 9>/tmp/mylockfile

Eu adicionei o #!/bin/bash .

Eu usei com sucesso esta forma de flock .

    
por 31.07.2017 / 15:25