
지난번에도 평소처럼 Vim을 사용하고 있었는데 이상한 점을 발견했습니다. 내가 한 일은 다음과 같습니다.
~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile
그런 다음 변경하고 :wq
. 꽤 정상입니다. 그러나 다음은:
~$ sudo chown root:root testfile
~$ sudo chmod 644 testfile
~$ sudo -k
~$ ls -l | grep testfile
-rw-r--r-- root root 0 Jul 23 10:02 testfile
~$ vim testfile
따라서 루트에는 r/w 액세스 권한이 있어야 하며 다른 모든 사람은 읽기 권한만 가져야 합니다. 파일을 편집하고 저장해 보십시오. 불가능합니다. 훌륭합니다. 의도한 대로 작동합니다. 그러나 로 저장하면 :w!
vim은 어떻게든 파일 소유권을 다시 username:usergroup으로 변경하고 파일이 저장됩니다. 이렇게 해도:
~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile
당신은 할 수 있습니다아직으로 덮어쓰세요 :w!
! 무슨 일이 일어나고 있나요? 어떻게 vim이 이와 같은 파일 소유권 및 허가 법칙을 위반할 수 있습니까? 나는 vim의 도움말 페이지를 보고 :help :w
다음과 같은 내용을 찾았습니다.
:w[rite]! [++opt] Like ":write", but forcefully write when 'readonly' is set or there is another reason why writing was refused.
Note: This may change the permission and ownership of the file and break (symbolic) links. Add the 'W' flage to 'cpoptions' to avoid this.
이전에는 파일에 쓸 수 없어야 했는데 vim에서 파일에 쓸 수 없었기 때문에 제 질문의 진짜 핵심은 vim에서 파일을 편집할 수 없게 만드는 방법과 파일을 기반으로 하지 않는 이유입니다. 예상한 시스템 권한과 다른 편집자(gedit, nano)가 사용할 수 없는 파일을 편집하기 위해 vim이 사용하는 메커니즘은 무엇입니까?
편집: 내가 시도한 컴퓨터는 Linux 커널 3.15.5-2-ARCH를 사용하고 있습니다. Vim의 버전 번호는 7.4.373-1이고, Vim이 설치한 버전입니다 pacman
. 특별한 옵션을 사용하여 처음부터 컴파일하지 않았습니다.
답변1
~
현재 경로는 사용자의 홈 디렉터리 인 것을 알 수 있습니다 . 해당 디렉터리에 대한 쓰기 권한이 있어야 합니다.
다른 방식으로 생각해 보십시오. 디렉토리에 대한 읽기 및 쓰기 권한이 있는 경우 파일 복사, 이전 파일 삭제 및 다른 권한으로 새 파일 이름 바꾸기를 방해하는 이유는 무엇입니까?
예를 들어 strace에서 vim을 실행하는 경우:
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)
lstat("testfile", {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
getuid() = 1000
unlink("testfile") = 0
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
write(3, "ffjidfjds\n", 10) = 10
fsync(3) = 0
close(3) = 0
chmod("testfile", 0644) = 0
이 로그를 바탕으로 다음 프로세스를 추측할 수 있습니다.
간결성을 위해 일부 이전 권한 확인(및 chown
시도 등)은 생략되었습니다.
open
쓰기 위해 파일을 열려고 시도했습니다(실패: 권한이 거부됨).lstat
파일의 소유자를 확인하세요getuuid
현재 사용자 ID를 확인하여 파일 소유자와 일치하는지 확인하세요.unlink
파일 삭제(디렉토리에 대한 쓰기 권한 때문에 허용됨)open
같은 이름으로 새 파일 만들기write
파일 내용(앞에서 읽었으며 횡설수설을 입력했습니다)fsync
파일을 디스크로 플러시(별로 중요하지 않음)close
chmod
새 파일의 권한을 이전 파일처럼 보이도록 변경하세요. 이제 새 소유자가 생겼습니다.