Lưu ý : Vì lý do cấp phép cũ, hầu hết các bản phân phối GNU / Linux không bao gồm chương trình vi gốc như được viết bởi Bill Joy. Thay vào đó, lệnh vi được cung cấp bằng cách chạy Vim ở chế độ tương thích vi. Câu trả lời sau dựa trên việc chạy Vim với chế độ tương thích vi.
Sửa đổi tệp chỉ đọc
Vim cảnh báo người dùng nếu họ sửa đổi bộ đệm của tệp chỉ đọc , W10: Warning: Changing a readonly file
. Nếu người dùng cố gắng ghi vào tệp này, họ sẽ nhận được thông báo lỗi sau 'readonly' option is set (add ! to override)
.
Khi thư mục mẹ có thể ghi bởi người dùng Vim
Vim, rất hữu ích, cho người dùng biết rằng họ có thể khăng khăng đòi viết bằng cách gắn thêm dấu chấm than !
vào w
lệnh. Nếu phiên bản mạnh mẽ này của lệnh ghi được sử dụng, Vim sẽ xóa tệp gốc (nếu sử dụng Vim với bộ backup
tùy chọn chỉ Vim , tệp gốc thực sự được đổi tên thành giống như tệp sao lưu). Sau đó, nó sẽ mở (tạo) một tệp mới có cùng tên với bản gốc và ghi nội dung của bộ đệm vào tệp mới này. Điều này có thể được quan sát bằng cách kiểm tra nút inode của tệp trước và sau khi chạy 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
Lưu ý: Điều này cũng có thể thay đổi quyền và quyền sở hữu tệp và ngắt liên kết (tượng trưng), ví dụ: nếu tệp gốc được sở hữu bởi người dùng khác, tệp mới sẽ thuộc sở hữu của người dùng đang chạy Vim.
Một quy trình chỉ có thể làm điều này nếu nó có quyền ghi cho thư mục mẹ của tệp. Nói chung, để đảm bảo rằng một chương trình không thể sửa đổi một tệp, các quyền của cả chính tệp đó và thư mục mẹ của nó phải được bảo mật.
Khi thư mục mẹ không thể ghi được bởi người dùng Vim
Tuy nhiên, ngay cả trong trường hợp này, Vim vẫn cố gắng hết sức để giúp người dùng khăng khăng ghi đè lên tệp. Nếu người dùng Vim có quyền sở hữu tệp, Vim có thể khắc phục hạn chế thư mục mẹ chỉ đọc bằng cách thay đổi tạm thời quyền của tệp (sử dụng lệnh chmod
gọi hệ thống), ghi bộ đệm vào tệp, đóng tệp và sau đó thay đổi tệp quyền trở lại. Đây là một trích xuất của các cuộc gọi hệ thống được thực hiện trong khi chạy vi thông qua 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
Lưu ý: Điều này không xảy ra nếu người dùng Vim đang chỉnh sửa một tệp mà họ không có quyền sở hữu vì Vim sẽ không thể thay đổi quyền của tệp.
Phụ lục
Để thực sự chắc chắn rằng một tệp không thể được sửa đổi (trên hệ thống GNU / Linux), hãy chạy chattr
lệnh dưới dạng siêu người dùng:
sudo chattr +i filename
Từ man chattr
:
Không thể sửa đổi tệp có thuộc tính 'i': không thể xóa hoặc đổi tên, không thể tạo liên kết đến tệp này và không có dữ liệu nào có thể được ghi vào tệp. Chỉ có siêu người dùng hoặc một quá trình sở hữu khả năng CAP_LINUX_IMMUTABLE mới có thể đặt hoặc xóa thuộc tính này.