ในวันที่ 19 ส.ค. 2556 Randal L. Schwartzโพสต์สคริปต์เชลล์นี้ซึ่งมีจุดประสงค์เพื่อให้แน่ใจว่าบน Linux "ว่ามีเพียงหนึ่งตัวอย่างของสคริปต์ [the] ที่กำลังทำงานโดยไม่มีเงื่อนไขการแข่งขันหรือต้องล้างไฟล์ล็อค":
#!/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
ดูเหมือนว่าจะทำงานตามที่โฆษณาไว้:
$ ./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
$
นี่คือสิ่งที่ฉันเข้าใจ:
- สคริปต์เปลี่ยนเส้นทาง (
<
) คัดลอกเนื้อหาของตัวเอง (เช่นจาก$0
) ไปยัง STDIN (เช่น file descriptor0
) ของ subshell - ภายใน subshell ที่พยายามสคริปต์ที่จะได้รับไม่ปิดกั้น, ล็อคพิเศษ (
flock -n -x
)0
บนไฟล์อธิบาย- หากความพยายามนั้นล้มเหลว subshell จะออก (และสคริปต์หลักจะทำเช่นนั้นเนื่องจากไม่มีสิ่งอื่นใดให้ทำ)
- หากความพยายามแทนสำเร็จ subshell จะรันงานที่ต้องการ
นี่คือคำถามของฉัน:
- ทำไมสคริปต์ต้องเปลี่ยนเส้นทางไปยังตัวอธิบายไฟล์ที่สืบทอดโดย subshell สำเนาของเนื้อหาของตัวเองแทนที่จะพูดเนื้อหาของไฟล์อื่น ๆ ? (ฉันพยายามเปลี่ยนเส้นทางจากไฟล์ที่แตกต่างกันและเรียกใช้อีกครั้งตามลำดับและการดำเนินการเปลี่ยนแปลง: งานที่ไม่ได้รับพื้นหลังได้รับการล็อคก่อนแบ็คกราวน์หนึ่งดังนั้นอาจใช้เนื้อหาของไฟล์เองเพื่อหลีกเลี่ยงสภาพการแข่งขัน
- ทำไมสคริปต์ต้องเปลี่ยนเส้นทางไปยังตัวอธิบายไฟล์ที่สืบทอดโดย subshell ซึ่งเป็นสำเนาของเนื้อหาของไฟล์หรือไม่?
- ทำไมถือล็อคพิเศษที่บ่งไฟล์
0
ในหนึ่งเปลือกป้องกันไม่ให้สำเนาของสคริปต์เดียวกันวิ่งในเปลือกที่แตกต่างกันจากการล็อคพิเศษในไฟล์อธิบาย0
? อย่าเปลือกหอยมีของตัวเองสำเนาแยกของพวกเขาของอธิบายไฟล์มาตรฐาน (0
,1
และ2
เช่น STDIN, STDOUT และ STDERR)?