Vi สามารถเขียนเป็นไฟล์ได้แม้ไฟล์จะเป็นแบบอ่านอย่างเดียว


12

ตัวอย่างต่อไปนี้แสดงวิธีสร้างไฟล์ที่มีสิทธิ์อ่านเท่านั้น ในฐานะที่เราสามารถมองเห็นเมื่อฉันพยายามที่จะเขียนถึงไฟล์นี้โดยใช้คำสั่ง echo Permission deniedที่ผมได้รับ

แต่ทำไมในกรณีที่เราใช้ vi เราไม่ได้รับPermission denied? ดังที่เห็นได้จากที่นี่เราสามารถเขียนลงไฟล์ได้แม้ว่าไฟล์นั้นจะเป็นแบบอ่านอย่างเดียว

เกิดอะไรขึ้นที่นี่ นี่เป็นข้อผิดพลาด vi หรือไม่

[admin@madona-machine1 ~]$ touch test-file
[admin@madona-machine1 ~]$ ls -ltr
total 0
-rw-r--r-- 1 admin admin 0 Apr 13 07:32 test-file
[admin@madona-machine1 ~]$ chmod -w  test-file
[admin@madona-machine1 ~]$ ls -ltr
total 0
-r--r--r-- 1 admin admin 0 Apr 13 07:32 test-file
[admin@madona-machine1 ~]$ echo try_to_write > test-file
-bash: test-file: Permission denied
[admin@madona-machine1 ~]$ vi test-file

I am good singer,

 ~
 ~
 ~
 ~
 ~
 ~
 ~                                                
   "test-file" 1L, 4C written

1
FYI มีไซต์เบต้า SE สำหรับสิ่งนี้ - vi.stackexchange.com
Raystafarian

คำตอบ:


28

หมายเหตุ : เนื่องจากเหตุผลการออกใบอนุญาตแบบดั้งเดิมการแจกแจง GNU / Linux ส่วนใหญ่จึงไม่รวมโปรแกรม vi ต้นฉบับตามที่เขียนโดย Bill Joy แต่คำสั่ง vi ถูกจัดเตรียมโดยการรัน Vim ในโหมดความเข้ากันได้ของ vi คำตอบต่อไปนี้ขึ้นอยู่กับการรัน Vim ด้วยโหมดความเข้ากันได้ของ vi

การแก้ไขไฟล์แบบอ่านอย่างเดียว

Vim เตือนผู้ใช้หากพวกเขาแก้ไขบัฟเฟอร์ของไฟล์อ่านอย่างเดียว, W10: Warning: Changing a readonly file. 'readonly' option is set (add ! to override)หากผู้ใช้พยายามเขียนไฟล์นี้พวกเขาได้รับข้อความแสดงข้อผิดพลาดต่อไปนี้

เมื่อไดเร็กทอรีหลักสามารถเขียนได้โดยผู้ใช้ Vim

เป็นกลุ่มช่วยให้ผู้ใช้ทราบว่าพวกเขาสามารถยืนยันอย่างแรงในการเขียนได้โดยการใส่เครื่องหมายอัศเจรีย์ต่อท้าย!ลงในwคำสั่ง หากใช้เวอร์ชันคำสั่ง write ที่แรงนี้ Vim จะลบไฟล์ต้นฉบับ (หากใช้ Vim ด้วยbackupชุดตัวเลือกVim-only ไฟล์ต้นฉบับจะถูกเปลี่ยนชื่อเป็นไฟล์สำรองข้อมูลจริง) จากนั้นจะเปิด (สร้าง) ไฟล์ใหม่ที่มีชื่อเหมือนกับต้นฉบับและเขียนเนื้อหาของบัฟเฟอร์ลงในไฟล์ใหม่นี้ สิ่งนี้สามารถสังเกตได้โดยการตรวจสอบinodeของไฟล์ก่อนและหลังการเรียกใช้ Vim:

$ ls -l --inode t

131529 -r--r--r-- 1 anthony anthony 0 Apr 13 09:23 t

$ vi t
$ ls -l --inode t

131649 -r--r--r-- 1 anthony anthony 4 Apr 13 09:23 t

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

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

เมื่อไดเร็กทอรีพาเรนต์ไม่สามารถเขียนได้โดยผู้ใช้ Vim

อย่างไรก็ตามแม้ในกรณีนี้ Vim ยังคงพยายามอย่างดีที่สุดเพื่อช่วยให้ผู้ใช้ที่มีปัญหาสามารถเขียนทับไฟล์ได้ หากผู้ใช้ที่เป็นกลุ่มมีความเป็นเจ้าของไฟล์ Vim สามารถหลีกเลี่ยงข้อ จำกัด ของไดเรกทอรีหลักแบบอ่านอย่างเดียวโดยการเปลี่ยนการอนุญาตของไฟล์ชั่วคราว (โดยใช้การchmodเรียกระบบ) เขียนบัฟเฟอร์ลงในไฟล์ปิดไฟล์แล้วเปลี่ยน สิทธิ์กลับ นี่เป็นส่วนหนึ่งของการเรียกระบบที่เรียกใช้ในขณะที่เรียกใช้ vi ถึง strace strace -o ../vi.trace vi t:

getuid()                                = 501
chmod("t", 0100644)                     = 0
open("t", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "I am good singer,\n", 18)     = 18
fsync(4)                                = 0
close(4)                                = 0
chmod("t", 0100444)                     = 0

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

ภาคผนวก

เพื่อให้แน่ใจว่าไฟล์นั้นไม่สามารถแก้ไขได้ (บนระบบ GNU / Linux) ให้รันchattrคำสั่งเป็น superuser:

sudo chattr +i filename

จากman chattr:

ไฟล์ที่มีแอตทริบิวต์ 'i' ไม่สามารถแก้ไขได้: ไม่สามารถลบหรือเปลี่ยนชื่อได้ไม่มีการสร้างลิงก์ในไฟล์นี้และไม่สามารถเขียนข้อมูลลงในไฟล์ได้ เฉพาะ superuser หรือกระบวนการที่มีความสามารถ CAP_LINUX_IMMUTABLE เท่านั้นที่สามารถตั้งค่าหรือล้างแอตทริบิวต์นี้


2
ควันศักดิ์สิทธิ์นั่นคือทั้งหมด!
Camille Goudeseune

4
@CamilleGoudeseune หลังจากที่ฉันโพสต์รุ่นแรกของคำตอบของฉันฉันได้ทำการทดลองบางอย่างและลงเอยด้วยการใช้ Vim ผ่าน strace เพื่อดูว่ามันกำลังทำอะไรอยู่เบื้องหลังในสถานการณ์ที่แตกต่างกัน (การเปลี่ยนลำดับการอนุญาตที่แตกต่างกัน ไดเรกทอรีหลัก) บางครั้งฉันก็ถูกพาตัวไป แต่เมื่อฉันเผยแพร่คำตอบแล้วฉันต้องการแน่ใจว่าสิ่งที่ฉันพูดนั้นถูกต้อง
Anthony Geoghegan

5

ส่วนใหญ่ถ้าไม่ทุกviการใช้งานที่ทำให้คุณไม่สามารถเขียนไฟล์ถ้าคุณใช้เป็นประจำคำสั่งบันทึกเหมือนอย่างใดอย่างหนึ่งZZ, :w, :wqหรือ:x, เช่นกับvim:

:w
E45: 'readonly' option is set (add ! to override)

ในทางกลับกันถ้าคุณบอกviให้เขียนไฟล์แม้จะมีการอนุญาตด้วยการใช้บางอย่างเช่น:x!หรือ:wq!เอดิเตอร์กำลังคลายสิทธิ์ชั่วคราวเพื่ออนุญาตให้เขียนไฟล์:

...
stat("test-file", {st_mode=S_IFREG|0444, st_size=7, ...}) = 0
getuid()                                = 1000
chmod("test-file", 0100644)             = 0
...
open("test-file", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "I am good singer,\n", 18)               = 18
fsync(4)                                = 0
close(4)                                = 0
chmod("test-file", 0100444)             = 0
....

ในกรณีนั้นหมายเลขไอโหนดจะไม่เปลี่ยนแปลง

viสุดท้ายนี้ไม่ได้เป็นข้อผิดพลาดเช่นถ้าคุณไม่ได้รับอนุญาตให้เปลี่ยนสิทธิ์ของแฟ้มที่คุณไม่สามารถแก้ไขได้ผ่าน


ฮะ! หลังจากที่ฉันโพสต์คำตอบของฉันฉันได้ทำการทดลองบางอย่างและใช้เวลาเกือบชั่วโมงในการใช้ Vim ผ่าน strace เพื่อดูว่ามันทำอะไรอยู่เบื้องหลังในสถานการณ์ที่แตกต่างกัน ฉันเพิ่งเห็นคำตอบของคุณหลังจากที่สรุปผลการทดลองของฉันเสร็จแล้ว มันเป็นประสบการณ์การเรียนรู้ที่ดี
Anthony Geoghegan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.