Pase múltiples comandos al rebaño

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

¿Cómo pasaría múltiples comandos flockcomo en el ejemplo anterior?

Según tengo entendido, flocktoma diferentes indicadores (-x para exclusivo, -w para tiempo de espera), luego el archivo para bloquear y luego el comando para ejecutar. No estoy seguro de cómo pasaría dos comandos a esta función (establezca la variable con el contenido del archivo bloqueado y luego incremente este archivo).

Mi objetivo aquí es crear un incremento algo atómico para un archivo bloqueándolo cada vez que un script intenta acceder al counter.txtarchivo.

d -_- b
fuente

Respuestas:

8

Invocar un shell explícitamente.

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

Tenga en cuenta que cualquier variable que cambie es local para esa instancia de shell. Por ejemplo, la COUNTERvariable no se actualizará en el script de llamada: deberá volver a leerla desde el archivo (pero puede haber cambiado mientras tanto), o como la salida del comando:

new_counter=$(flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) | tee ~/counter.txt')
Gilles 'SO- deja de ser malvado'
fuente
increíble, muchas gracias! La explicación que proporcionó definitivamente me salvó de otra hora de dolores de cabeza
d -_- b
4

O puede agrupar un descriptor de archivo

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

Esto también tiene el beneficio de permitirle usar la variable de contador directamente, a diferencia de los enfoques basados ​​en subshell.

Richard Maw
fuente
Por favor, ¿podrías explicarme exec {counterfd}? Por sí solo, errores de Debian not found, pero devuelve 0 con la redirección. Muy raro.
Steve Almond el
2

La flockherramienta es un poco difícil de usar y la página de manual es bastante corta. La página del manual proporciona tres formas de usar la herramienta:

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

La forma en que está formulada esta pregunta definitivamente usaría la tercera forma de flock. Si va más abajo en la página del manual, flockhay algunos ejemplos que muestran la sintaxis exacta para usar el tercer formulario:

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

Agregué el #!/bin/bash.

He utilizado con éxito esta forma de flock.

Trevor Boyd Smith
fuente