Il 19 agosto 2013, Randal L. Schwartz ha pubblicato questo script di shell, che aveva lo scopo di garantire, su Linux, "che sia in esecuzione solo un'istanza di [lo] script, senza condizioni di competizione o che debba ripulire i file di blocco":
#!/bin/sh
# randal_l_schwartz_001.sh
(
if ! flock -n -x 0
then
echo "$$ cannot get flock"
exit 0
fi
echo "$$ start"
sleep 10 # for testing. put the real task here
echo "$$ end"
) < $0
Sembra funzionare come pubblicizzato:
$ ./randal_l_schwartz_001.sh & ./randal_l_schwartz_001.sh
[1] 11863
11863 start
11864 cannot get flock
$ 11863 end
[1]+ Done ./randal_l_schwartz_001.sh
$
Ecco cosa capisco:
- Lo script reindirizza (
<) una copia del proprio contenuto (ovvero da$0) allo STDIN (ovvero descrittore di file0) di una subshell. - All'interno della subshell, lo script tenta di ottenere un blocco esclusivo (
flock -n -x) non bloccante sul descrittore di file0.- Se quel tentativo fallisce, la subshell esce (e così fa lo script principale, poiché non c'è nient'altro da fare).
- Se invece il tentativo ha esito positivo, la subshell esegue l'attività desiderata.
Ecco le mie domande:
- Perché lo script deve reindirizzare, a un descrittore di file ereditato dalla subshell, una copia del proprio contenuto anziché, diciamo, il contenuto di qualche altro file? (Ho provato a reindirizzare da un file diverso e rieseguire come sopra, e l'ordine di esecuzione è cambiato: l'attività non in background ha ottenuto il blocco prima di quello in background. Quindi, forse usando i contenuti del file si evitano le condizioni di gara; ma come?)
- Perché lo script deve reindirizzare, a un descrittore di file ereditato dalla subshell, una copia del contenuto di un file, comunque?
- Perché tenere un blocco esclusivo sul descrittore di file
0in una shell impedisce a una copia dello stesso script, eseguita in una shell diversa, di ottenere un blocco esclusivo sul descrittore di file0? Non conchiglie hanno le proprie, copie separate dei descrittori di file standard (0,1, e2, cioè STDIN, stdout e stderr)?