Vào ngày 19 tháng 8 năm 2013, Randal L. Schwartz đã đăng tập lệnh shell này , nhằm đảm bảo, trên Linux, "chỉ có một phiên bản của tập lệnh [đang chạy], không có điều kiện chạy đua hoặc phải dọn sạch các tệp khóa":
#!/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
Nó dường như hoạt động như quảng cáo:
$ ./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
$
Đây là những gì tôi hiểu:
- Kịch bản chuyển hướng (
<
) một bản sao nội dung của chính nó (tức là từ$0
) sang STDIN (tức là mô tả tệp0
) của một khung con. - Trong lớp con, tập lệnh cố gắng để có được một khóa độc quyền, không khóa (
flock -n -x
) trên bộ mô tả tệp0
.- Nếu lần thử đó thất bại, lớp con thoát ra (và kịch bản chính cũng vậy, vì nó không có gì khác để làm).
- Nếu nỗ lực thay vào đó thành công, lớp con sẽ chạy tác vụ mong muốn.
Đây là câu hỏi của tôi:
- Tại sao tập lệnh cần chuyển hướng, đến một bộ mô tả tệp được kế thừa bởi lớp con, một bản sao nội dung của chính nó chứ không phải là nội dung của một số tệp khác? .
- Tại sao tập lệnh cần phải chuyển hướng, đến một bộ mô tả tệp được kế thừa bởi lớp con, một bản sao nội dung của tệp, dù sao?
- Tại sao việc giữ một khóa độc quyền trên bộ mô tả tệp
0
trong một trình bao ngăn chặn một bản sao của cùng một tập lệnh, chạy trong một trình bao khác, để có được một khóa độc quyền trên bộ mô tả tệp0
? Đừng vỏ có riêng, bản riêng của họ về file descriptor chuẩn (0
,1
, và2
, tức là STDIN, STDOUT, và stderr)?