Passa più comandi al gregge


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

Come passerei più comandi a flockcome nell'esempio sopra?

Per quanto ho capito, flockaccetta diversi flag (-x per esclusivi, -w per timeout), quindi il file da bloccare, quindi il comando da eseguire. Non sono sicuro di come passare due comandi in questa funzione (imposta la variabile con il contenuto del file bloccato e quindi incrementa questo file).

Il mio obiettivo qui è quello di creare un incremento un po 'atomico per un file bloccandolo ogni volta che uno script tenta di accedere al counter.txtfile.

Risposte:


8

Richiamare esplicitamente una shell.

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

Si noti che qualsiasi variabile modificata è locale all'istanza della shell. Ad esempio, la COUNTERvariabile non verrà aggiornata nello script chiamante: dovrai rileggerla dal file (ma nel frattempo potrebbe essere cambiata) o come output del comando:

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

fantastico, grazie mille! La spiegazione che mi hai fornito mi ha sicuramente salvato da un'altra ora di mal di testa
d -_- b

4

Oppure puoi floccare un descrittore di file

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

Ciò ha anche il vantaggio di consentire all'utente di utilizzare direttamente la variabile counter, diversamente dagli approcci basati su subshell.


Per favore, spiegheresti il exec {counterfd}? Di per sé, errori Debian not found, ma restituisce 0 con il reindirizzamento. Molto strano.
Steve Almond,

2

Lo flockstrumento è un po 'complicato da usare e la pagina man è piuttosto breve. La pagina man offre tre modi per usare lo strumento:

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

Nel modo in cui questa domanda è formulata, utilizzerei sicuramente la terza forma di flock. Se vai più in basso nella pagina man per flockci sono alcuni esempi che mostrano l'esatta sintassi per l'utilizzo del terzo modulo:

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

Ho aggiunto il #!/bin/bash.

Ho usato con successo questa forma di flock.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.