2015-06-05 8 views
7

Prima lasciami mostrare cosa funziona. Se utilizzo flock con il percorso del file, funziona.Impossibile bloccare il file utilizzando il flock con il descrittore di file

Terminal 1:

[[email protected] ~]# flock -x -n /tmp/foo.txt -c "sleep 100" 

Terminal 2:

[[email protected] ~]# flock -x -n /tmp/foo.txt -c "sleep 100" 
[[email protected] ~]# echo $? 
1 

L'output sopra mostra che ho acquisire un blocco esclusivo /tmp/foo.txt nel primo terminale. Quindi nel secondo terminale, quando provo ad acquisire un blocco sullo stesso file, fallisce.

Ora fammi sapere cosa non funziona. Se uso il flock con il descrittore di file, non funziona.

Terminal 1:

[[email protected] ~]# { flock -x -n 100; sleep 100; } 100> /tmp/foo.txt 

Terminal 2:

[[email protected] ~]# { flock -x -n 100; sleep 100; } 100> /tmp/foo.txt 

L'output sopra mostra che provo prima di acquisire un blocco sul /tmp/foo.txt nel primo terminale. Quindi nel secondo terminale, quando provo ad acquisire un blocco sullo stesso file, ci riesce. Mi aspettavo che fallisse proprio come nell'esempio precedente. Perché ha successo?

risposta

10

Si sta utilizzando -n che terminerà se il blocco non può essere acquisito immediatamente e flock non riuscirà con il codice di uscita 1. Quindi dopo aver eseguito il codice nel primo terminale, si dorme per 100 secondi. Successivamente, quando si esegue lo stesso in un altro terminale, flock fallisce e restituisce 1, ma poiché esiste un ; e non si esegue alcuna operazione con il codice di ritorno, la shell continua semplicemente a eseguire l'istruzione successiva e dorme per 100 secondi.

Pertanto è necessario prendere una decisione sul codice di ritorno del gruppo come indicato di seguito.

(flock -x -n 100 || exit 55; sleep 100;) 100> /tmp/foo.txt 

Ora se si esegue la linea sopra in un terminale, esso si spegnerà per 100 secondi. Quindi, se si esegue il codice su un altro terminale, si tornerà immediatamente al prompt. Fai un echo $? e vedrai che è stato restituito 55 perché volevamo tornare usando lo ||.

Cosa fa || in cortocircuito. Se flock restituisce 0 come in uscita normale che è un valore vero per la shell, non eseguirà il lato destro dell'espressione e quindi passerà alla successiva istruzione. Se il valore restituito è 1 ovvero false per la shell, continuerà a valutare l'espressione sul lato destro che è exit 55 e quindi uscire. Puoi farlo anche con if-then-fi.

Si noti inoltre che ho utilizzato le parentesi () anziché le parentesi graffe {}. Questo perché, se usi le parentesi graffe, i comandi verranno eseguiti nella shell corrente e, se usi exit, uscirà dalla shell corrente. Una parentesi creerà una subshell, quindi facendo un exit da qui si termina la subshell e si torna alla shell originale.

Ha funzionato per il primo esempio utilizzando -c perché è disponibile il comando singolo incluso nell'argomento flock. Pertanto se flock non è in grado di acquisire il blocco, semplicemente non eseguirà l'istruzione e terminerà.

Problemi correlati