読み取り専用ファイルを変更できるのはなぜですか?


42

短い質問:

管理者でなくても、:+ w+ q+ を使用してVimで読み取り専用ファイルを操作できるのはなぜ!ですか?

長い質問:

すべてのユーザーに対して読み取り専用のテキストファイル(myFile.txt)があります。

navid@navid-ThinkPad-T530:~/ubuntuTest$ ls -l myFile.txt 
-r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt

管理者権限がなくてもVimで開くことができます。

navid@navid-ThinkPad-T530:~/ubuntuTest$ vi myFile.txt 

私はそれを修正して押します:Esc+ :+ w+ q+ Enterそしてこのエラーメッセージを見ます:

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

これまでのところ、すべてが理にかなっています。しかし、Esc+ :+ w+ q+ !+ を押すとEnter、Vimは変更を保存します。

Ubuntu 16.04とVIM 7.4を使用しています。


1
@Zannaファイルが入っているディレクトリを所有していますか?
ロブ

そうでなければ、これは大きな問題になります:)
ロブ

11
ファイルの変更とファイルの置換は、異なる許可要件を持つ2つの異なるものです。
デビッドシュワルツ

1
これを見たいかもしれません。それは基本的にあなたの質問に答え、@ DavidSchwartzが正しく指摘したようにModifying a file and replacing a file are two different things
パナギオティスタバキス

@PanagiotisTabakisこれは素晴らしいです非常に素晴らしい発見あなたがそれを所有している場合..ファイルを作るためにはchmodが再び書き込みを読んで... LOVE ITは:)
ロブ・

回答:


58

@Robが既に述べたように、ファイルを含むディレクトリへの書き込みアクセス権がある場合にのみこれを行うことができます。たとえば、ファイルに対して同じことをしようとする/etcと失敗します。

これを行う方法について vimは、ファイルを削除して再作成します。これをテストするために、rootが所有するファイルを作成しました。

echo foo | sudo tee fff

そして、vimあなたが説明した方法でファイルを編集しましたが、プロセスを添付してstrace何が起こっているかを確認しました:

strace vim fff 2> strace.out

私はそれからチェックstrace.outして見つけました:

unlink("fff")                           = 0
open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "foasdasdao\n", 11)            = 11

そのため、ファイルが最初に削除され(unlink("fff"))、次に同じ名前の新しいファイルが作成され(open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644))、行った変更がそれに書き込まれました(write(4, "foasdasdao\n", 11))。自宅でこれを試してみると、で編集した後vim、ファイルはルートではなくあなたのものになります。

厳密に言えば、vim書き込みアクセス権のないファイルを編集することではありません。書き込みアクセス権のあるディレクトリからファイルを削除してから、書き込みアクセス権のある新しいファイルを作成しています。



8
@CCJこれは、ディレクトリではなくファイルの書き込み操作です。ファイルに対する書き込み操作は、ファイルの内容を変更する操作です。同様に、ファイルの作成/削除は、その内容を変更しているため、ディレクトリに対する書き込み操作です。
テルドン

2
また、それは操作の危険な順序です。置換を新しいファイル名に書き込み、それを使用rename(2)して古いファイルを置換する方が安全です。その後、データがディスク上に存在しない時間枠はありません。
ピーターコーデス

5
@PeterCordesええと、わかりました。ただし、vim開発者に苦情を送ることもできます。私はその物さえ使いません、私はemacsキャンプにいます。
テルドン

3
@CCJファイルの削除は、ファイル自体ではなく、ファイルを含むディレクトリへの書き込み操作です。ディレクトリを管理している(つまり、そのディレクトリへの書き込みアクセス権がある)場合、その中にあるものを制御できるはずであり、個々のファイルの所有者があなたをオーバーライドすることは許可されないはずです。
fkraiem

16

親ディレクトリを所有している限り、ディレクトリの内容を変更できるため、許可に関係なくファイルを削除または置換できます:)。

rmなどの他のコマンドで試してください。プロンプトが表示されますが、まだ実行できます。ディレクトリを書き込み不可にすると、停止します。

添加:

試しただけですが、ファイルを所有している限り、フォルダが読み取り専用であっても変更できます。ただし、所有権をroot:rootに変更すると、ファイルを書き込み用に開くことができません。そのため、root(または他の誰か)が所有する変更ファイルを解決します


7
VIMは新しいファイルのインプレース書き換えまたはリンク解除+書き込みなど、複数の戦略から選択するようです。
ピーターコーデス

3
@PeterCordesはいそれは明らかにあなたがそれを伝えることを非常に一生懸命しようとします:)非常に巧妙です。:)
ロブ

16

w!あなたを使用すると、元のファイル(あなたが行うことが許可されている)を削除し、代わりにあなたのバージョンを書いています。

ディレクトリへの書き込みアクセス権がある場合、次のことができます。そのディレクトリ内でファイルを作成、移動、または削除します。

$ mkdir foo
$ echo hi > foo/file
$ chmod 777 foo
$ chmod 700 foo/file
$ ls -l foo/file 
-rwx------ 1 ravexina ravexina 7 Aug 31 03:19 foo/file

ユーザーを切り替えてファイルを変更します

$ sudo -u user2 -s
$ vi foo/a # save using w! (I wrote into the file bye)
$ ls -l foo/a
-rwx------ 1 user2 user2 7 Aug 31 03:20 foo/file

そこに何があるか見てみましょう:

$ cat foo/file
bye

10

参照:help write-readonly

                                                        write-readonly
When the 'cpoptions' option contains 'W', Vim will refuse to overwrite a
readonly file.  When 'W' is not present, ":w!" will overwrite a readonly file,
if the system allows it (the directory must be writable).

ディレクトリに対する書き込み権限があるため(ディレクトリ内のファイルを作成、削除、または名前変更できることを意味します)、システムはそれを許可します。


のデフォルト値にcpoptionsは以下が含まれていませんW

                                                'cpoptions' 'cpo' cpo
'cpoptions' 'cpo'       string  (Vim default: "aABceFs",
                                 Vi default:  all flags)
                        global

2

これはVIMからの警告であり、UNIXで権限がどのように機能するかを考えると比較的重要かもしれません。これの明らかな直感的ではない理由は、UNIXファイルシステムがファイルのiノードに保存されたファイルに対する許可を持っているためです。ディレクトリ構造は何らかの形で分離されており、これらのiノードのみをリンクしています。ディレクトリには、ファイルのリンク/リンク解除、読み取り、またはサブディレクトリへの移動を許可する権限もあります。この設計により、同じファイルをディレクトリ構造の複数の異なる場所に(ハードリンクを介して)表示できます。「オーバーライド!オーバーライド」と言うことで、VIMは元のファイルがリンク解除され(他のすべての場所にそのまま残る)、新しいファイルが作成され、ディレクトリ構造の元の場所にリンクされることを警告しようとしています。元のファイルのリンクカウントがゼロに減少した場合、元のファイルは解放されますが、そうでない場合は、ファイルを効果的に複製しています。ファイルを開くこともリンクとしてカウントされるため、あるプログラムがファイルを開き、「追加!オーバーライド」に同意する場合、VIMを使用してファイルに加えられた変更はプログラムに表示されません。ファイルはVIMによってディレクトリからリンク解除されるだけで、別のプログラムによってファイルを閉じた後、他の場所にリンクされていない限り、ファイルは解放されます。

Windowsでは、ファイルのアクセス許可はディレクトリに保存されるため、Windowsアクセス許可のパラダイムの観点からは、このvimの動作は実際には奇妙に見える場合があります。ファイルへの書き込みについて、Windowsは論理的に、一部のディレクトリアクセス許可、スーパーディレクトリアクセス許可もチェックする場合があります。上記のように、UNIXでは、ファイルをリストして開くことができる限り(つまり、すべてのスーパーディレクトリにxがあった)、ディレクトリのアクセス権はファイルの操作には無関係です。UNIXで開かれたファイルは、開いた後にすべてのディレクトリからリンク解除された場合、ファイル名さえもなくなる可能性があります。

たとえば、ファイル/ home / user1 / fooがあり、それが/ home / user2 / fooと同じ(つまり、ハードリンクされている)ファイルであり、このファイルは誰でも書き込み可能ではなく、現在プログラムPで開かれている(読み取り/書き込みで開かれている)ルートによって開始されたプログラム)。user1がvimでそれを開いて上書きすると、ユーザー1は自分のコピーを作成し、元のファイルは表示されなくなります。その後、user2がvimでリンクを開いて書き込みを行うと、再びリンクが解除され、別のコピーが作成されます。プログラムPは元のファイルを引き続き表示し、自由に読み書きできます。プログラムがファイルを閉じるとすぐに、ファイルは消えます(ファイルシステムによって解放されます)。


2

vimエディタープロセスとファイルの両方に、

 getpwnam("navid")->pw_uid

所有権があるので、シェルアウトすることもできます

 :!chmod +w %

かつてはもっとシンプルだったと思うかもしれません

 :!rm %

(所有者ではなく。

姉のを上書きしてみてください

 /home/whoopi/.profile

あなたのVimはあなたの希望する拒否を与えるだけです。


@Zanna、コードの編集に感謝しますが、初心者には少し評判が上がりましたが、当然です。
ローマンチボラ

1

これは正確な答えではありませんが、ファイルを変更したり削除したりできないように設定したい場合は、不変にすることができます。

通常、ファイルがルートによって所有されている場合でも、フォルダへの書き込み権限がある場合はファイルを削除できます。しかし、ファイルを不変にすると、rootでさえ変更または削除できなくなります。

ファイルを不変にするには(必要sudo):

sudo chattr +i myFile.txt

これはlsattri結果の文字)で見ることができます:

$ lsattr myFile.txt
----i--------e-- myFile.txt

ファイルを再び正常にするには:

sudo chattr -i myFile.txt

明確にするために:ファイルが不変である場合、削除、名前変更、変更、またはハードリンクさえできません。

man chattrファイルには多くの有用な属性があるため、読む価値があります。

「制限付き削除」も役立つ場合があります。(ファイルではなく)フォルダーに配置されている場合、これは、フォルダー内でファイルを作成する人は誰でもそのファイルを変更または削除することを許可されますが、他のユーザーは許可されないことを意味します(ルートを除く)。フォルダーに/tmpはこのフラグが設定されています。tonフラグでこれを見ることができます/tmp

$ ls -l --directory /tmp
drwxrwxrwt 10 root root 4096 Sep  6 09:00 /tmp

フォルダーの制限付き削除フラグを設定または削除するには:

chmod +t myFolder      # Add the restricted deletion flag.
chmod -t myFolder      # Remove the restricted deletion flag.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.