Passe vários comandos para reunir

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

Como eu passaria vários comandos para flocko exemplo acima?

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

Meu objetivo aqui é criar um incremento atômico para um arquivo, bloqueando-o toda vez que um script tenta acessar o counter.txtarquivo.

d -_- b
fonte

Respostas:

7

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 COUNTERvariável não será atualizada no script de chamada: você precisará lê-la novamente a partir do arquivo (mas pode ter sido alterada nesse meio tempo) ou como a saída do comando:

new_counter=$(flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) | tee ~/counter.txt')
Gilles 'SO- parar de ser mau'
fonte
incrível, muito obrigado! A explicação que você forneceu definitivamente me salvou de mais uma hora de dores de cabeça
d -_- b
4

Ou você pode reunir um descritor de arquivo

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

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

Richard Maw
fonte
Por favor, você explicaria o exec {counterfd}? Por si só, o Debian erros not found, mas retorna 0 com o redirecionamento. Muito estranho.
21819 Steve Almond
2

A flockferramenta é um pouco complicada de usar e a página de manual é bastante curta. A página do manual 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>

Como esta pergunta está formulada, eu definitivamente usaria a terceira forma de flock. Se você for mais adiante na página de manual, flockhá 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 tenho usado com sucesso este formulário de flock.

Trevor Boyd Smith
fonte