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


13

ฉันพยายามsedแทนที่คำหลักบางคำในไฟล์ขนาดใหญ่ (100 MB) ฉันไม่รู้-iตัวเลือก (inplace) ดังนั้นความพยายามครั้งแรกของฉันคือเปลี่ยนเส้นทางดังนี้:

sed 's/original/edited/g' file.log >> file.log

เกิดอะไรขึ้นหลังจากนั้นก็คือว่าพีซีของฉันหยุดชะงักแทบจะไม่มีการป้อนข้อมูลด้วยแป้นพิมพ์ ฉันพยายามที่แตกต่างกันคอนโซลCtrl+ Alt+ F1แต่หลังจากที่ช้าป้อนชื่อผู้ใช้ก็หยุดเกินไป ไม่มีคีย์บอร์ดตัวเลือกเดียวของฉันคือการรีเซ็ตฮาร์ดแวร์ของเครื่อง หลังจากเข้าสู่ระบบฉันเห็นว่า file.log มีขนาดประมาณ 8 GB

ฉันอยากจะเข้าใจว่าทำไมการดำเนินการของคำสั่งนั้นจึงทำให้ระบบไม่ตอบสนองและหากมีกลไกที่ระดับระบบเพื่อกระตุ้นการแจ้งเตือนและฆ่ากระบวนการที่กระทำผิด


7
นี่เป็นเครื่องแกนเดียวหรือไม่? ดูเหมือนแปลกมากที่สิ่งนี้น่าจะนำคอมพิวเตอร์ที่ทันสมัยมาคุกเข่า เติมดิสก์ของคุณใช่ ใช้คอร์ของคุณ 100% ใช่แล้ว แต่ผิดพลาดเต็มหรือไม่
terdon

มีอะไรแปลกประหลาดเกี่ยวกับไฟล์นั้นหรือไม่? หากนี่ไม่ใช่ปัญหาคุณสามารถโพสต์เนื้อหาลงใน Pastebin ได้หรือไม่?
Sergiy Kolodyazhnyy

นอกจากนี้จำนวนหน่วยความจำของคุณคืออะไร? คุณสามารถให้ผลลัพธ์กับเราได้free -h ไหม
Sergiy Kolodyazhnyy

เหตุใดจึงต้องใช้ตัวแก้ไขสตรีมตั้งแต่แรกเมื่อคุณต้องการเปลี่ยนไฟล์ ex -sc '%s/original/edited/ge|x' file.logควรทำสิ่งที่คุณต้องการในลักษณะสำนวน UNIX โดยไม่มีsed -iผลข้างเคียง
David Ongaro

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

คำตอบ:


10

ดังที่ได้กล่าวไปแล้ว>>ผนวกเข้ากับไฟล์ดังนั้นsedคำสั่งของคุณจะอยู่ที่นั่นเพื่ออ่านบรรทัดที่เพิ่งมีเอาต์พุตและจากนั้นให้เพิ่มอีก ถ้าคุณอยากจะเปลี่ยนไฟล์ของคุณในสถานที่>ยังคงจะไม่ทำงาน แต่คุณตระหนักถึงsed's -iตัวเลือกซึ่งเป็นมั่นเหมาะหนึ่งที่คุณต้องการ

อย่างไรก็ตามหากคุณมั่นใจอย่างยิ่งว่าคุณต้องการผนวกไฟล์ที่คุณกำลังอ่านเป็นสตรีมและต้องการทำสิ่งนี้ผ่านหนึ่งครั้งให้พิจารณาใช้spongeจากmoreutilsแพ็คเกจ

sed 's/original/edited/g' file.log | sponge >> file.log

spongeอ่านจาก stdin ไปยังหน่วยความจำจนกระทั่ง EOF แล้วทิ้งเนื้อหาทั้งหมดลงใน stdout ดังนั้นsedจะกดจุดสิ้นสุดของไฟล์หยุดอ่านปิดและจากนั้นฟองน้ำจะเริ่มต่อท้าย


2
spongeเป็นยูทิลิตี้ที่น่ารู้ แต่sedมี-iตัวเลือกอยู่แล้ว: -i[SUFFIX], --in-place[=SUFFIX], edit files in place (makes backup if SUFFIX supplied).
Joshua Taylor

@JoshuaTaylor, OP กำลังใช้>>งานซึ่งต่อท้ายมากกว่า>ที่จะแทนที่ จริงอยู่ที่ OP ได้กล่าวถึงเฉพาะ-iในโพสต์และดูเหมือนว่าเป็นกรณีการใช้งานทั่วไปที่ไกลกว่านี้ แต่ฉันคิดว่ามันคุ้มค่าที่จะชี้ให้เห็นว่าการดำเนินการเฉพาะที่ OP ได้โพสต์นั้นเป็นไปได้โดยไม่ยุ่งยากมากเกินไป แน่ใจว่าเป็นสิ่งที่คุณต้องการทำ
ymbirtt

1
ที่ผมกล่าวถึงที่นี่เพราะมันเป็นกุญแจสำคัญในการที่คำตอบที่ได้รับการยอมรับ ที่กล่าวว่าฉันรู้สึกมีความสุขอย่างแท้จริงที่จะเรียนรู้เกี่ยวกับฟองน้ำ ; มันเป็นเครื่องมือใหม่สำหรับกล่องเครื่องมือของฉันและคุ้มค่าสำหรับ upvote
Joshua Taylor

1
อา! ฉันเห็น. ฉันจะปรับแต่งคำตอบเพื่อให้ชัดเจนขึ้น นอกจากนี้ถ้าคุณมีความสุขใช้เวลาดูที่sponge เป็นเพียงชุดมหัศจรรย์ที่เต็มไปด้วยสิ่งที่คุณไม่เคยรู้มาก่อนว่าคุณต้องการvipemoreutils
ymbirtt

18

sedคำสั่งของคุณกำลังพยายามอ่านไฟล์ที่กำลังผนวกอยู่ มันจะไม่ถึง End-Of-File แต่จะกิน CPU เป็นจำนวนมากพยายาม นั่นเป็นเหตุผลที่ ^ C (กระบวนการขัดจังหวะในปัจจุบัน) ถูกคิดค้น


ฉันไม่คิดว่า ^ C เป็นตัวเลือกที่นั่น ... มันไปที่ HALT นั่นคือไม่มีเคอร์เซอร์กะพริบติดอยู่!
EKons

18

การผนวกกลับไปที่ไฟล์ที่คุณอ่านจะไม่มีความคิดที่ดีเนื่องจากคุณจะพบไฟล์ที่กำลังเติบโต หากคุณต้องการเขียนกลับไปที่ไฟล์จริง ๆ คุณควรใช้การ-iตั้งค่าสถานะ:

sed -i 's/original/edited/g' file.log

หรือถ้าคุณต้องการให้มันสร้างการสำรองข้อมูลก่อนทำการเปลี่ยนแปลงคุณสามารถเพิ่มคำต่อท้ายไฟล์ลงใน-iแฟล็ก:

sed -i.bak 's/original/edited/g' file.log

สิ่งนี้จะสร้างไฟล์ชื่อfile.log.bakแล้วทำการเปลี่ยนแปลงสิ่งที่คุณทำที่นั่นโดยพยายามผนวกไฟล์ที่คุณอ่านจากที่เราเรียกใน programang แสลงที่ data ที่กระบวนการต่าง ๆ แย่งกันอยู่ในแหล่งข้อมูลเดียวกันไม่ว่าจะเป็น input หรือ output . นี่คือสาเหตุที่เครื่องของคุณหยุดชะงัก


1
ฉันประหลาดใจที่นี่เป็นคำตอบที่ยอมรับเพราะมันไม่ได้ตอบคำถามของ OP"I really would like to understand why the execution of that command was able to make the system so unresponsive, and if mechanisms exist at the system level to trigger alerts and kill the offending process?"
Steve

@ Steve เพราะเหตุใดฉันจึงหยุดพูด แต่ส่วนที่สองคุณพูดถูก ฉันไม่ได้พูดถึงเรื่องนี้เพราะฉันไม่รู้คำตอบสำหรับเรื่องนี้ เราทดสอบคำสั่งหลังจากการสนทนาอย่างกว้างขวางและได้ผลลัพธ์ที่แตกต่างกันโดยสิ้นเชิงในเครื่องและระบบปฏิบัติการที่แตกต่างกัน ตัวอย่าง: บนเครื่องที่มีส่วนโค้งจะอนุญาตให้ไฟล์ขยายตลอดไป แต่จะไม่ทำให้เครื่องไม่ตอบสนอง บนเครื่อง Ubuntu ของฉันฉันได้รับผลลัพธ์เช่นเดียวกับผู้ถามโดยไม่มีโอกาสฆ่ากระบวนการ เครื่องที่สองทดสอบเหมือนกันใน Ubuntu VM มาถึงหยุดชะงักเดียวกัน
Videonauth

straceของกระบวนการทั้งหมดใน didtn ด้านอื่น ๆ ทำซ้ำผลและนี้ในเครื่องของฉันและบนเครื่องของผู้ใช้อื่น ๆ แน่นอนว่ามีกลไกที่คุณสามารถฆ่าแอปพลิเคชั่นที่ไม่ตอบสนองได้ แต่หากเครื่องของคุณไม่ตอบสนองคุณจะเหลือเพียงตัวเลือกเดียวเท่านั้นที่จะรีเซ็ตมัน ฉันยังคงทดสอบเกี่ยวกับเรื่องนี้และก่อนที่ฉันจะไม่เข้าใจสิ่งที่เป็นสาเหตุของพฤติกรรมที่อธิบายไว้อย่างสมบูรณ์ฉันไม่สามารถตอบคำถามนี้ได้
Videonauth

อาจเป็นความแตกต่างในการกำหนดค่าเคอร์เนลเช่นตัวกำหนดเวลาที่แตกต่างกันซึ่งจัดลำดับความสำคัญของ IO หรือความแตกต่างในไดรเวอร์ดิสก์ / ระบบไฟล์ระหว่างระบบ เป็นเรื่องดีที่ได้เห็นการสอบสวนที่พวกคุณทำนั่นเป็นข้อมูลที่ดี
Steve

หากคุณสนใจจุดข้อมูลอื่น ฉันลองสิ่งนี้ในเครื่อง CentOS ด้วยไฟล์ที่ค่อนข้างเล็กและมันก็ทำสิ่งเดียวกันกับฟองน้ำของฉันด้านล่าง ฉันจินตนาการว่าสำหรับไฟล์ขนาดเล็กsedจะบัฟเฟอร์สิ่งทั้งหมดลงในหน่วยความจำแล้วปิดมันแทนที่จะเก็บที่จับไว้ ด้วยไฟล์ ~ 100MB เช่นเดียวกับใน OP มันจะเพิ่มขึ้นอย่างไม่มีกำหนด แต่ไม่ได้สร้างเครื่อง
ymbirtt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.