W dniu 19 sierpnia 2013 r. Randal L. Schwartz opublikował ten skrypt powłoki, który miał zapewnić w systemie Linux, że „działa tylko jedna instancja skryptu [bez] warunków wyścigu lub konieczności czyszczenia plików blokujących”:
#!/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
Wygląda na to, że działa zgodnie z reklamą:
$ ./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
$
Oto, co rozumiem:
- Skrypt przekierowuje (
<
) kopię własnej zawartości (tj. Z$0
) do STDIN (tj. Deskryptora pliku0
) podpowłoki. - W ramach podpowłoki skrypt próbuje uzyskać nieblokującą, wyłączną blokadę (
flock -n -x
) deskryptora pliku0
.- Jeśli ta próba się nie powiedzie, podpowłoka kończy działanie (podobnie jak główny skrypt, ponieważ nie ma nic więcej do zrobienia).
- Jeśli próba zakończy się powodzeniem, podpowłoka uruchamia żądane zadanie.
Oto moje pytania:
- Dlaczego skrypt musi przekierowywać do deskryptora pliku odziedziczonego przez podpowłokę kopię własnej zawartości zamiast, powiedzmy, zawartości innego pliku? (Próbowałem przekierować z innego pliku i uruchomić ponownie jak wyżej, a kolejność wykonywania uległa zmianie: zadanie bez tła zyskało blokadę przed drugim. Więc może użycie własnej zawartości pliku pozwala uniknąć warunków wyścigu; ale jak?)
- Dlaczego w każdym razie skrypt musi przekierowywać do deskryptora pliku odziedziczonego przez podpowłokę, kopię zawartości pliku?
- Dlaczego trzymanie wyłącznej blokady deskryptora pliku
0
w jednej powłoce uniemożliwia kopii tego samego skryptu działającego w innej powłoce uzyskanie wyłącznej blokady deskryptora pliku0
? Nie muszle mają swoje własne, oddzielne kopie standardowych deskryptorów (0
,1
, i2
, tj stdin, stdout i stderr)?