왜 읽기 전용 파일을 수정할 수 있습니까?


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+ !+를 누르면 EnterVim이 변경 사항을 저장합니다.

Ubuntu 16.04 및 VIM 7.4를 사용하고 있습니다.


1
@Zanna 파일이있는 디렉토리를 소유하고 있습니까?
Rob

네, 그렇지 않으면 엄청나게 큰 문제 일 것입니다 :)
Rob

11
파일 수정과 파일 교체는 서로 다른 권한 요구 사항을 가진 두 가지입니다.
David Schwartz

1
이것을 보고 싶을 수도 있습니다 . 그것은 기본적으로 귀하의 질문에 대답하고 @DavidSchwartz가 올바르게 지적했듯이 :Modifying a file and replacing a file are two different things
Panagiotis Tabakis

@PanagiotisTabakis 아주 좋은 발견이 훌륭합니다.. chmod는 파일을 읽고 쓸 수 있도록하고 다시 소유하고 있다면 다시 되돌립니다 .. IT를 사랑하십시오 :)
Rob

답변:


58

@Rob에서 이미 언급했듯이 파일이 포함 된 디렉토리에 대한 쓰기 권한이있는 경우에만이 작업을 수행 할 수 있습니다. 예를 들어, 파일에서 동일한 작업을 수행하려고 /etc하면 실패합니다.

에 관해서는 어떻게 vim 이 일을, 그것은 파일을 삭제하고 다시 만듭니다. 이를 테스트하기 위해 루트가 소유 한 파일을 작성했습니다.

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 디렉토리 에 대한 쓰기 작업 이지만 파일은 아닙니다. 파일에 대한 쓰기 작업은 파일 내용을 변경하는 작업입니다. 마찬가지로, 파일 작성 / 삭제는 내용을 변경하므로 디렉토리에서 쓰기 작업입니다.
terdon

2
또한 위험한 작업 순서입니다. 대체 파일을 새 파일 이름으로 쓴 다음 rename(2)이전 파일을 바꾸는 데 더 안전 합니다. 그런 다음 데이터가 디스크에 존재하지 않는 시간 창이 없습니다.
Peter Cordes

5
@PeterCordes 음, 알았어. 그래도 불만을 vim 개발자에게 전달하고 싶을 수도 있습니다. 나는 심지어 그것을 사용하지 않고, 나는 이맥스 캠프에 있습니다.
terdon

3
@CCJ 파일 삭제는 파일 자체가 아니라 파일을 포함하는 디렉토리에 대한 쓰기 작업입니다. 디렉토리를 담당하는 경우 (즉, 디렉토리에 대한 쓰기 액세스 권한이있는 경우) 디렉토리의 내용을 제어 할 수 있어야하며 개별 파일의 소유자가 사용자를 대체 할 수 없어야합니다.
fkraiem

16

부모 디렉토리를 소유하고 있다면 디렉토리의 내용을 변경할 수 있으므로 권한에 관계없이 파일을 제거하거나 바꿀 수 있습니다 :).

rm과 같은 다른 명령으로 시도하면 프롬프트가 표시되지만 여전히 수행 할 수 있습니다. 디렉토리를 쓰기 불가능하게 만들고 중지해야합니다.

부가:

그냥 시도했지만 파일을 소유하고있는 한 폴더 읽기 만해도 파일을 수정할 수 있습니다. 그러나 소유권을 root : root로 변경하면 쓰기 위해 파일을 열 수 없습니다. 따라서 루트 (또는 다른 사람)가 소유 한 수정 파일을 해결합니다.


7
VIM이 제자리에서 재 작성 또는 새 파일의 링크 해제 + 쓰기를 포함한 여러 전략 중에서 선택하는 것처럼 들립니다.
Peter Cordes

3
@PeterCordes 예 그것은 당신이 말한 것을하기 위해 아주 열심히 노력할 것입니다 :) 매우 교활합니다. :)
Rob

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).

디렉토리에 대한 쓰기 권한이 있으므로 (파일을 작성, 삭제 또는 이름을 바꿀 수 있음) 시스템에서 허용합니다.


기본값 cpoptionsW다음을 포함하지 않습니다 .

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

2

이것은 UNIX에서 권한이 작동하는 방식을 고려할 때 상대적으로 중요 할 수있는 VIM의 경고입니다. 직관적이지 않은 것은 UNIX 파일 시스템이 파일의 i- 노드에 저장된 파일에 대한 권한을 가지고 있기 때문입니다. 디렉토리 구조는 어떻게 든 분리되어 있으며 이러한 i- 노드 만 링크합니다. 디렉토리에는 파일을 파일에 링크 / 링크 해제 할 수 있는지 또는 서브 디렉토리를 탐색 할 수 있는지를 나타내는 권한이 있습니다. 이 디자인을 사용하면 동일한 파일이 디렉토리 구조의 여러 위치 (하드 링크를 통해)에 나타날 수 있습니다. "오버라이드에 추가!"라고 말하면 VIM은 원본 파일의 연결이 해제되고 다른 모든 위치에는 그대로 유지되며 새 파일이 생성되어 디렉토리 구조의 원래 위치에 연결됨을 경고합니다. 원본 파일의 링크 수가 0으로 감소하면 원본 파일은 해제되지만 그렇지 않으면 효과적으로 파일을 복제하는 것입니다. 파일을 여는 것도 링크로 간주되므로 일부 프로그램이 파일을 열고 "add! to override"에 동의하면 VIM을 사용하여 파일의 변경 사항을 볼 수 없습니다. 파일은 VIM에 의해 디렉토리에서만 링크 해제되며 다른 프로그램에 의해 파일을 닫은 후 다른 위치에 링크되어 있지 않으면 파일이 해제됩니다.

Windows에서 파일에 대한 권한은 디렉토리에 저장되므로 Windows 권한 패러다임의 관점에서이 vim 동작은 실제로 이상하게 보일 수 있습니다. 파일에 쓰기 위해 Windows는 논리적으로 일부 디렉토리 권한, 심지어 슈퍼 디렉토리 권한도 검사 할 수 있습니다. 위에서 말한 것처럼, UNIX에서 디렉토리 권한은 파일을 나열하고 열 수있는 한 (즉, 모든 수퍼 디렉토리에 대해 x가있는 경우) 파일 조작과 관련이 없습니다. UNIX에서 열린 파일은 파일을 연 후 모든 디렉토리에서 연결 해제 된 경우 더 이상 파일 이름을 갖지 않을 수 있습니다.

예를 들어, 파일 / home / user1 / foo가 있고 / home / user2 / foo와 동일한 파일 (예 : 하드 링크로 연결됨)이며 다른 사람이 파일을 쓸 수 없으며 현재 프로그램 P에 의해 열려 있습니다 (읽기 / 쓰기로 열린 상태) 루트로 시작된 프로그램). user1이 vim으로 파일을 열고 덮어 쓰면 직접 복사하여 더 이상 원본 파일을 볼 수 없습니다. 그 다음에 user2가 vim으로 링크를 열어서 쓰면 다시 연결 해제되고 다른 사본을 작성합니다. 프로그램 P는 여전히 원본 파일을보고 자유롭게 읽거나 쓸 수 있습니다. 프로그램이 파일을 닫 자마자 파일이 사라집니다 (파일 시스템에 의해 해제 됨).


2

귀하의 vim 편집기 프로세스와 파일 모두

 getpwnam("navid")->pw_uid

당신이 또한 껍질을 벗길 수 있도록 소유권

 :!chmod +w %

그리고 당신은 한 번에 훨씬 더 간단하다고 추측 할 수 있습니다

 :!rm %

(+ w 만 필요하지만 링크에 대한 링크 권한 및 소유권조차 없음)이 너무 자주 입력되어 입력하기에는 vim이 자동으로 제공되고 요청시 자동으로 그러한 작업을 수행하도록 다시 프로그래밍되었습니다.

언니의 덮어 쓰기

 /home/whoopi/.profile

단지 순진하고 내기 인 것처럼 당신의 vim은 당신에게 원하는 거절을 제공합니다.


그래도 초보자에게는 약간의 평판이 들었지만 코드 편집에 대해 @Zanna에게 감사드립니다.
로마

1

이것은 정답은 아니지만 파일을 변경하거나 삭제할 수 없도록 파일을 실제로 설정하려면 변경할 수 없습니다.

일반적으로 루트가 파일을 소유 한 경우에도 폴더에 대한 쓰기 권한이 있으면 파일을 삭제할 수 있습니다. 그러나 파일을 변경할 수 없게 만들면 루트조차도 파일을 수정하거나 삭제할 수 없습니다.

파일을 불변으로 만들려면 (필요한 sudo) :

sudo chattr +i myFile.txt

당신은 이것을 lsattr( i결과 의 문자) 와 함께 볼 수 있습니다 :

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

파일을 다시 정상으로 만들려면

sudo chattr -i myFile.txt

명확히하려면 : 파일을 변경할 수없는 경우 파일을 삭제, 이름 변경, 수정 또는 하드 링크 할 수 없습니다.

man chattr파일에는 여러 가지 유용한 속성이있을 수 있으므로 읽을 가치가 있습니다.

"제한된 삭제"가 유용 할 수도 있습니다. 파일이 아닌 폴더에있는 경우 폴더 내에서 파일을 만드는 사람은 해당 파일을 수정하거나 삭제할 수 있지만 다른 사람은 없습니다 (루트 제외). 폴더 /tmp에는이 플래그가 설정되어 있습니다. 이 t플래그를 /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.