ทำการดำเนินการเขียนอะตอมมิกในไฟล์ในทุบตี


13

หลังจากผ่านเอกสาร bash แล้วคำถามนี้และคำถามนี้ยังไม่ชัดเจนสำหรับฉันฉันจะดำเนินการเขียนอะตอม (ผนวก) ไปยังไฟล์ใน bash ได้อย่างไร ฉันมีสคริปต์ที่ทำงานในหลายกรณีและบางจุดต้องเขียนข้อมูลไปยังไฟล์:

echo "$RESULT" >> `pwd`/$TEMP_DIR/$OUT_FILE

เป็นไปได้อย่างไรที่จะทำการเขียนทั้งหมดจากสคริปต์ที่รันพร้อมกันไปยังไฟล์อะตอมมิก (ดังนั้นข้อมูลจากอินสแตนซ์หนึ่งจะไม่ซ้อนทับข้อมูลจากอีกอัน)


1
FYI คุณไม่จำเป็นต้อง`pwd`; คุณสามารถใช้จุด ( .) นอกจากนี้คุณควรจะพูดชื่อแฟ้มที่ทั้งเพราะมันมีตัวแปร
Wildcard

1
นอกจากนี้คุณยังอาจต้องการที่จะมองเข้าไปในความเป็นไปได้ของการใช้ FIFOs
Wildcard

@ Wildcard ขอบคุณ ฉันใช้pwdสคริปต์ก่อนหน้านี้เพื่อแจ้งผู้ใช้เกี่ยวกับไดเรกทอรีการทำงานปัจจุบันและเขียนรายการในไฟล์บันทึก มองไปที่ FIFOs ตอนนี้
Sebi

1
จริงๆแล้วมีการแนะนำ FIFO ที่ดีกว่าในเว็บไซต์นี้ ลิงก์ที่ฉันให้ไว้ไม่กี่นาทีที่ผ่านมาเป็นข้อกำหนด POSIX mkfifoและไม่ใช่ระดับเกริ่นนำ
Wildcard

ไม่ว่าจะเป็น FIFO หรือไฟล์คุณยังคงเสี่ยงต่อการที่สองอินสแตนซ์เขียนในเวลาเดียวกันและบิดเบือนผลลัพธ์ของกันและกัน
พูดยั่วยุ

คำตอบ:


10

ดูเหมือนว่าคุณจำเป็นต้องใช้flockในตัวอย่างจาก man ( http://linux.die.net/man/1/flock )

(
flock -x 200

# Put here your commands that must do some writes atomically

) 200>/var/lock/mylockfile 

และวางคำสั่งทั้งหมดของคุณที่จะต้องมีอะตอมมิกใน ()


การดำเนินการเขียนจะเป็น atomic แม้ว่า (flock -s 200 # ใส่คำสั่งของคุณที่ต้องเขียนแบบ atom) 200> / var / lock / mylockfile หรือในทางกลับกันล็อคจะสัมพันธ์กับ / var / lock / mylockfile เท่านั้น?
Sebi

1
สคริปต์ของคุณล็อค / var / lock / mylockfile แต่มีเพียงหนึ่งอินสแตนซ์ของสคริปต์ของคุณเท่านั้นที่สามารถล็อคการเขียนได้ อินสแตนซ์อื่น ๆ จะรอจนกว่า/var/lock/mylockfileจะพร้อมใช้งานสำหรับการล็อก

-s เป็นล็อคที่ใช้ร่วมกัน - เหมาะสำหรับการอ่านสำหรับล็อคการเขียนคุณต้องใช้ -x / -e มันอยู่ใน man page ที่คุณเชื่อมโยง
Evan Benn

การปลดล็อกเกิดขึ้นที่จุดใดในรหัสนี้ เร็วที่สุดเท่าที่บางสิ่งบางอย่างได้รับการเขียนไป/var/lock/mylockfileโดยกระบวนการที่เรียกว่าflock -x?
Chris Stryczynski

@ChrisStryczynski คุณสามารถเรียกใช้ตัวอย่างนี้(flock -x 200; date; sleep 10; date;) 200>/var/lock/mylockfileในสองเชลล์และดูว่าการปลดล็อกเกิดขึ้นหลังจากคำสั่งทั้งหมดใน () ถูกเรียกใช้ (ซึ่งอยู่ใน subshell)

4

flockเป็นหนึ่งในวิธีการประสานการทำงาน ยูทิลิตี้นี้เป็นส่วนหนึ่งของชุดเครื่องมือ util-linux และพร้อมใช้งานสำหรับ Linux เท่านั้น ยูทิลิตี้อื่น ๆ ที่มีอยู่ในแพลตฟอร์มที่กว้างขึ้นนั้นมีพื้นฐานsetlockมาจากสาธารณูปโภคของ Daniel J. Bernstein จากแพ็คเกจ daemontools ของเขา:

  • setlock จาก daemontools
  • setlock จาก daemontools-encore ของ Bruce Guenter
  • s6-setlock จาก s6 Laurent Bercot
  • chpst จาก runit ของ Gerrit Pape
  • runlock จาก perp ของ Wayne Marshall
  • setlock จากชุดเครื่องมือของฉัน

เครื่องมือเหล่านี้ทำงานด้วยกระบวนทัศน์ที่แตกต่างกันเล็กน้อยกับที่ใช้ในคำตอบของ M. Kurenkov (เครื่องมือหนึ่งที่flockสามารถใช้งานได้ แต่ไม่ได้อยู่ในคำตอบนั้น) หนึ่งเรียกใช้setlockโปรแกรมเพื่อโยงโหลดไปยังคำสั่งที่ต้องถูกเชื่อมโยงกัน setlockตัวเองเปิดและล็อคไฟล์ล็อคและปล่อยให้ไฟล์อธิบายมันเปิดในกระบวนการของมัน การล็อกยังคงอยู่ตราบใดที่กระบวนการนั้นทำ (ยกเว้นว่าคำสั่งที่ตามมาถูกโยงโซ่เพื่อปลดล็อกอย่างชัดเจนโดยการค้นหาและปิดตัวอธิบายไฟล์ที่เปิด)

สำหรับกรณีในคำถามเราต้องเชื่อมคำสั่งที่ก่อให้เกิดบรรทัดเอาต์พุตโดยระวังว่าสิ่งนี้เรียกใช้งานภายนอก echoแทนechoคำสั่งในตัวของเชลล์:

setlock mylockfile echo "$ RESULT" >> ./$TEMP_DIR/$OUT_FILE

ในกรณีนี้มันไม่จำเป็นต้องเชื่อมต่อกันเปิดไฟล์ที่ส่งออกในโหมดผนวก ถ้าเป็นเช่นนั้นเราจะต้องเปิดไฟล์นั้นภายในล็อคซึ่งจำเป็นต้องใช้โปรแกรมเช่นfdredir/ redirfd:

setlock mylockfile fdredir - ผนวก 1 "./$TEMP_DIR/$OUT_FILE" echo "$ RESULT"
อันไหนที่สามารถเปลี่ยนเป็นฟังก์ชันเชลล์ได้หากต้องการ:

outfile () {setlock mylockfile fdredir - ผนวก 1 "./$TEMP_DIR/$OUT_FILE" "$ @"; } 
[…]
outfile echo "$ RESULT"
หรือผสานกับไวยากรณ์เชลล์และตีความโดยเชลล์ที่สองที่ทำงานภายใต้ลูกโซ่ซึ่งต้องการการอ้างอิงที่ไม่สำคัญถ้าตัวแปรเชลล์ตัวใดตัวหนึ่งไม่ถูกส่งออกเป็นตัวแปรสภาพแวดล้อม:

setlock mylockfile sh -c 'echo' "$ RESULT" '>> "./'$TEMP_DIR'/'$OUT_FILE'" '

หลักสูตรนี้พูดคุยกับสิ่งอื่นที่ไม่ใช่การเขียนไปยังไฟล์เอาต์พุต:

setlock mylockfile sh -c '…เชื่อมต่อกัน; สิ่งที่ ... '

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.