ฉันสามารถแก้ไขไฟล์ bash script (.sh) ในขณะที่กำลังรันได้หรือไม่


28

สมมติว่าฉันมีสคริปต์script.shซึ่งใช้เวลาพอสมควรในการดำเนินการ ./script.shผมดำเนินการนั้น ในขณะที่มันกำลังทำงานในหน้าต่าง terminal script.shผมแก้ไขไฟล์ สิ่งนี้จะมีผลกระทบต่อกระบวนการที่กำลังทำงานอยู่หรือไม่?

หลังจากแก้ไขมันฉันรันไฟล์ที่แก้ไขดังนั้นฉันจึงมีสองกระบวนการที่ทำงานอยู่ในขณะนี้ ไม่เป็นไร


คำตอบ:


36

เมื่อคุณทำการเปลี่ยนแปลงสคริปต์ของคุณคุณทำการเปลี่ยนแปลงบนดิสก์ (ฮาร์ดดิสก์ - ที่เก็บข้อมูลถาวร); เมื่อคุณรันสคริปต์สคริปต์จะถูกโหลดไปยังหน่วยความจำ (RAM) ของคุณ

ดังนั้นการเปลี่ยนแปลงที่คุณทำกับสคริปต์จะไม่ส่งผลต่อสคริปต์ที่รันอยู่ซึ่งจะรันเวอร์ชันที่คุณเรียกใช้ก่อนที่จะทำการเปลี่ยนแปลงเหล่านั้น

อย่างไรก็ตามเมื่อคุณรันสคริปต์ที่เปลี่ยนแปลงอีกครั้งโดยไม่ยกเลิกอินสแตนซ์ที่รันอยู่ก่อนหน้านี้จะมีอินสแตนซ์สองตัวของสคริปต์ซึ่งมีการเปลี่ยนแปลงและเก่า

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

อัปเดต: ขอบคุณผู้ใช้ที่ลงทะเบียนสำหรับการชี้ให้ฉันตอบที่ดีกว่าใน Unix.stackexchange.com

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

ดังนั้นจึงไม่แนะนำให้เปลี่ยนสคริปต์ของคุณบนดิสก์ที่ทำงานอยู่ในขณะนี้สำหรับผลลัพธ์ที่ไม่สามารถคาดเดาได้: หยุดอินสแตนซ์ที่กำลังทำงานอยู่ก่อนจากนั้นปรับเปลี่ยนสคริปต์ของคุณจากนั้นเรียกใช้สคริปต์อีกครั้ง


11
ไม่ใช่คำตอบที่สมบูรณ์แบบอ่านunix.stackexchange.com/q/121013/55673
ผู้ใช้ที่ลงทะเบียน

@registereduser: ใช่แล้วคำถามนั้นทำให้ฉันนึกถึงบทเรียนระบบปฏิบัติการของฉัน จะแก้ไขคำตอบของฉันทันทีที่ฉันไปถึงเดสก์ท็อปของฉัน (บนโทรศัพท์ของฉันตอนนี้)
jobin

ฉันเดาว่าสำหรับสคริปต์สั้น ๆ น่าจะไม่มีปัญหา
becko

1
เมื่อฉันลองมันด้วย bash v3.2.48 (ดูที่นี่ ) มันไม่ได้บัฟเฟอร์เกินกว่าจุดสิ้นสุดของบรรทัด ฉันเพิ่งทดสอบกับ bash v4.3.0 และมันบัฟเฟอร์สคริปต์ทั้งหมด (สั้น) ดังนั้น ... ฉันจะไม่เชื่อในพฤติกรรมเฉพาะใด ๆ
Gordon Davisson

1
@ ลงทะเบียนผู้ใช้ไม่ได้กับ bash ทุกรุ่น - ดูตัวอย่างที่ฉันเชื่อมโยง
Gordon Davisson

4

ฉันจะเพิ่มสิ่งที่ฉันคิดว่ายังไม่ได้พูดในคำตอบอื่น ๆ ขึ้นอยู่กับว่าคุณแก้ไขไฟล์มากแค่ไหน การทำecho "stuff" >fileจากเชลล์ (อินสแตนซ์อื่น) จะเขียนทับไฟล์แน่นอนฉันคิดว่า แต่ถ้าคุณแก้ไขไฟล์ด้วยอินสแตนซ์emacsแล้วบันทึกสิ่งนี้จะไม่เกิดขึ้น แต่ที่นี่แก้ไขเปลี่ยนชื่อแฟ้มเก่าชื่อสำรองบางส่วน (อาจจะจริงลบสำรองข้อมูลก่อนหน้านี้) และจากนั้นเขียนเนื้อหาบัฟเฟอร์ของการปรับเปลี่ยนเป็นใหม่ไฟล์ที่มี (libreated ตอนนี้) ชื่อเก่า เนื่องจากเชลล์ (หรือล่ามอื่น ๆ ) ที่อ่านสคริปต์จะเปิดไฟล์เกือบจะแน่นอนเพียงครั้งเดียวเท่านั้นหลังจากนั้นจึงไม่ขึ้นอยู่กับที่อยู่ของชื่อไฟล์มันจะยังคงอ่านไฟล์ฟิสิคัลดิสก์ (ระบุโดยหมายเลขไอโหนด) ที่เชื่อมโยงกับชื่อไฟล์ในเวลาที่เปิด ดังนั้นแม้ว่ามันจะอ่านสคริปต์ในบล็อก (ซึ่งจะเป็นทางออกที่ง่ายที่สุดหากใช้บัฟเฟอร์ข้อความ I / O) มันจะยังคงอ่านบรรทัดจากอินสแตนซ์เก่าของไฟล์ซึ่งน่าจะไม่เปลี่ยนแปลงโดยการแก้ไขของคุณ


+1 ฉันใช้ Sublime Text เป็นเครื่องมือแก้ไขของฉัน คุณรู้ไหมว่ามันเปลี่ยนชื่อไฟล์ด้วยเช่นกันemacs?
becko

1
ฉันคิดว่าผู้แก้ไขส่วนใหญ่จะใช้รูปแบบการเปลี่ยนชื่อ (แม้ว่าพวกเขาไม่ควรเก็บเวอร์ชันสำรอง) เพื่อหลีกเลี่ยงความเสี่ยงที่หากเกิดความผิดพลาดขึ้นในระหว่างขั้นตอนการเขียนจะไม่มีข้อความที่สมบูรณ์เหมือนเดิม คุณสามารถตรวจสอบกับ "ls -i" (ซึ่งแสดงหมายเลข inode) ลักษณะการทำงานของโปรแกรมแก้ไขของคุณคืออะไร
Marc van Leeuwen

1

จำเป็นต้องได้รับการอัปเดตคำตอบข้างต้นขณะนี้ถูกต้องเพียงบางส่วนเท่านั้น:

ด้วยเวอร์ชันปัจจุบันของ bash การแก้ไขสคริปต์บนดิสก์ในขณะที่ทำงานอยู่จะทำให้ bash "ลอง" เพื่อโหลดการเปลี่ยนแปลงลงในหน่วยความจำและใช้สิ่งเหล่านี้ในสคริปต์ที่ทำงานอยู่ หากการเปลี่ยนแปลงของคุณมาหลังจากบรรทัดที่กำลังดำเนินการอยู่บรรทัดใหม่จะถูกโหลดและดำเนินการ แต่นี่เป็นการคาดเดาจากการทุบตีและอาจทำให้ถูกหรือผิด

วิธีที่ดีกว่าในการทำเช่นนี้คือลำดับของการดำเนินการดังต่อไปนี้: 1) โหลดสคริปต์ลงในหน่วยความจำ 2) ลบสคริปต์ออกจากดิสก์ 3) เขียนสคริปต์ใหม่ลงดิสก์โดยการลบรุ่นดิสก์ก่อนรุ่นหน่วยความจำจะสูญเสียการเชื่อมโยง ดังนั้นเมื่อคุณจัดหาเวอร์ชันใหม่ในขั้นตอนที่ 3 จะไม่มีการพยายามทุบตีเพื่อโหลดเนื้อหาใหม่ลงในเวอร์ชันหน่วยความจำ


0

โดยทั่วไป @ คำตอบของ jobin ถูกต้อง แต่ฉันจะเพิ่มคำตอบอื่น ๆ ที่อาจถึงจุดขึ้นอยู่กับสิ่งที่คุณต้องการทำ

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

หากคุณต้องการประพฤติพฤติกรรมของสคริปต์ในทันทีคุณมีปัญหาที่ยากขึ้น ฉันคาดว่าคุณจะต้องสร้างมันลงในรหัสของสคริปต์ สคริปต์ทุบตีสามารถจัดการสัญญาณได้ (เช่นสามารถจับสิ่งที่ชอบkill -USR1 [pid]) และสคริปต์สามารถตอบสนองได้โดยการโหลดรหัสใหม่ ดังนั้นคุณอาจได้ฟังก์ชั่นการทำงานใกล้เคียงกับที่คุณต้องการ แต่โดยไม่รู้ว่าคุณกำลังทำอะไรฉันไม่เห็นเหตุผลที่ดีที่จะทำสิ่งนี้และฉันสงสัยว่าถ้าคุณต้องการทำสิ่งที่ซับซ้อนนี้คุณอาจต้องการความซับซ้อนมากขึ้น ภาษาโปรแกรมที่จะทำ

หากคุณต้องการแฮ็คพฤติกรรมของสคริปต์ที่ใช้งานซึ่งไม่ได้เขียนไว้ในใจแสดงว่าคุณไม่มีโชค ฉันลังเลที่จะโทรหางานการเขียนโปรแกรมใด ๆ ที่เป็นไปไม่ได้ แต่ถ้าคุณมีทรัพยากรและทักษะสำหรับงานประเภทนี้คุณคงจะไม่ถามที่นี่

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