Pada 19 Agustus 2013, Randal L. Schwartz memposting skrip shell ini , yang dimaksudkan untuk memastikan, di Linux, "bahwa hanya satu instance skrip sedang berjalan, tanpa syarat balapan atau harus membersihkan file kunci":
#!/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
Tampaknya berfungsi seperti yang diiklankan:
$ ./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
$
Inilah yang saya mengerti:
- Script mengarahkan (
<
) salinan dari isinya sendiri (yaitu dari$0
) ke STDIN (yaitu deskriptor file0
) dari sebuah subkulit. - Dalam subkulit, skrip mencoba untuk mendapatkan kunci (
flock -n -x
) eksklusif non-pemblokiran pada deskriptor file0
.- Jika upaya itu gagal, subshell keluar (dan begitu juga skrip utama, karena tidak ada lagi yang bisa dilakukan).
- Jika upaya tersebut berhasil, subkulit menjalankan tugas yang diinginkan.
Ini pertanyaan saya:
- Mengapa skrip perlu diarahkan, ke deskriptor file yang diwarisi oleh subkulit, salinan kontennya sendiri, bukan, katakanlah, isi beberapa file lain? (Saya mencoba mengalihkan dari file yang berbeda dan menjalankan kembali seperti di atas, dan urutan eksekusi berubah: tugas non-latar belakang memperoleh kunci sebelum latar belakang. Jadi, mungkin menggunakan konten file sendiri menghindari kondisi ras; tetapi bagaimana?)
- Mengapa skrip perlu diarahkan, ke deskriptor file yang diwarisi oleh subkulit, salinan konten file?
- Mengapa memegang kunci eksklusif pada deskriptor file
0
dalam satu shell mencegah salinan script yang sama, berjalan di shell yang berbeda, dari mendapatkan kunci eksklusif pada deskriptor file0
? Jangan kerang memiliki sendiri, salinan yang terpisah mereka dari file deskriptor standar (0
,1
, dan2
, yaitu STDIN, STDOUT, dan stderr)?