注:レガシーライセンスの理由により、ほとんどのGNU / Linuxディストリビューションには、Bill Joyによって書かれたオリジナルのviプログラムが含まれていません。代わりに、viコマンドは、vi-compatibilityモードでVimを実行することにより提供されます。次の回答は、vi互換モードでVimを実行することに基づいています。
読み取り専用ファイルの変更
Vimは、読み取り専用ファイルのバッファーを変更すると、ユーザーに警告しますW10: Warning: Changing a readonly file
。ユーザーがこのファイルへの書き込みを試みると、次のエラーメッセージが表示されます'readonly' option is set (add ! to override)
。
親ディレクトリがVimユーザーによって書き込み可能な場合
Vimは、有用であること、彼らは強制的に、感嘆符を付加することにより、書き込みを主張することができ、ユーザを知ることができます!
にw
コマンドを。書き込みコマンドのこの強制バージョンが使用される場合、Vimは元のファイルを削除します(Vimのみのbackup
オプションが設定されたVimを使用する場合、元のファイルは実際にバックアップファイルと同じ名前に変更されます)。次に、元のファイルと同じ名前の新しいファイルを開き(作成し)、その新しいファイルにバッファーの内容を書き込みます。これは、Vimを実行する前後にファイルのiノードをチェックすることで確認できます。
$ 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ユーザーがファイルの所有権を持っている場合、Vimは一時的にファイルのパーミッションを変更し(chmod
システムコールを使用)、バッファーをファイルに書き込み、ファイルを閉じてから、許可を戻します。以下は、straceを使用してviを実行中に行われたシステムコールの抜粋です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
、スーパーユーザーとしてコマンドを実行します。
sudo chattr +i filename
からman chattr
:
「i」属性を持つファイルは変更できません。削除または名前の変更はできません。このファイルへのリンクは作成できず、ファイルにデータを書き込むこともできません。この属性を設定またはクリアできるのは、スーパーユーザーまたはCAP_LINUX_IMMUTABLE機能を持つプロセスのみです。