vi 내부의 파일에 대한 루트 권한을 얻습니까? [닫은]


245

구성 파일을 편집하는 동안 종종 vi로 파일을 열고 저장하려고 할 때 입력하지 않았다는 것을 알게됩니다.

sudo vi filename

vi sudo 권한을 부여하여 파일을 저장할 수있는 방법이 있습니까? 한참 전에 vi에 대한 내용을 찾는 동안 이것에 대해 뭔가를 본 것이 기억 나지만 지금은 찾을 수 없습니다.


어쩌면 그냥 홈 디렉토리에 사본을 저장하고 나중에 "sudo mv"
paan

답변:


296

% 는 현재 파일 이름으로 바뀌므로 다음을 사용할 수 있습니다.

:w !sudo tee %

( vim파일이 변경되었음을 감지하고 다시로드할지 여부를 묻습니다. [L]확인 대신에 예라고 말하십시오 .)

바로 가기로 자신의 명령을 정의 할 수 있습니다. 당신의 다음을 넣어 .vimrc:

command W w !sudo tee % >/dev/null

위와 같이 입력 :W<Enter>하면 파일을 저장할 수 있습니다. 내가 이것을 썼기 때문에, 나는 이것을 할 수있는 더 좋은 방법을 찾았다.

cmap w!! w !sudo tee >/dev/null %

이런 식으로 입력 :w!!하면 전체 명령 행으로 확장되어 커서를 끝에 남겨두고 원하는 %경우 파일 이름을 자신의 파일 이름으로 바꿀 수 있습니다 .


5
이것은 gvim에서 작동합니까? 명령을 실행하면 Vim이 암호를 요구하지만 입력을 수락하지 않습니다. 그것은 결국이 개 시도에 타임 아웃과는 말한다 :sudo: 1 incorrect password attempt
cmcginty

나는 gvim이 다르게 행동 할 이유가 없다고 생각한다. sudo 자체가 올바르게 작동한다고 확신 하는가?

새 파일을 저장하기 위해 루트 권한이 필요한 경우 %를 새 파일의 이름 (경로 포함)으로 바꾸십시오.
gvkv

때로는 사용자를 sudoer 파일에 먼저 추가하고 루트 사용자를 입력 한 다음 /etc/sudoers파일을 열고 your_username ALL=(ALL) ALL행 아래 에 추가 root ALL=(ALL) ALL하고 종료하고 저장해야합니다.
가장 멋진

1
@coolesting : 1) 당신이해야 할 다른 일들이 수천 개 있습니다… 우리는 그것들을 모두 나열 할 수는 없습니다. 2) 항상 사용해야 visudo합니다.

32

일반적으로 vi 프로세스의 유효 사용자 ID를 변경할 수 없지만 다음을 수행 할 수 있습니다.

:w !sudo tee myfile

1
:w !sudo tee % >/dev/null또는 :w !sudo dd of=%파일이 저장 될 때 파일의 내용이 에코되는 것을 피하십시오.
jamessan

이것이 어떻게 작동하는지 설명 할 수 있습니까? 나는 tee유닉스 파이프 명령을 !보고 쉘 명령을 삽입하는 것을 보았습니다 . 는 IS :w에 의해 파이프됩니다 표준 출력에 쓰기는 tee?
Eric Hu

4
@ 에릭, 맞아. "tee myfile"명령은 stdin을 myfile에 복사합니다. "sudo tee myfile"을 실행하면 동일한 작업을 수행 할 수 있지만, 티 프로세스는 루트가 소유하므로 myfile도 루트가 소유합니다. vi :에서 ": w! some command line"은 모든 행을 "some command line"으로 파이프합니다.
마크 해리슨

16

일반적인주의 사항

읽기 전용 파일 문제를 해결하는 가장 일반적인 방법은의 구현을 사용하여 수퍼 유저로서 현재 파일에 파이프를 여는 것입니다 sudo tee. 그러나 인터넷에서 찾은 가장 인기있는 모든 솔루션에는 몇 가지 잠재적 인 경고가 있습니다.

  • 파일뿐만 아니라 전체 파일이 터미널에 기록됩니다. 대용량 파일, 특히 네트워크 연결 속도가 느린 경우 속도가 느려질 수 있습니다.
  • 파일의 모드와 유사한 속성이 손실됩니다.
  • 특이한 문자 나 공백이있는 파일 경로는 올바르게 처리되지 않을 수 있습니다.

솔루션

이러한 모든 문제를 해결하려면 다음 명령을 사용하십시오.

" On POSIX (Linux/Mac/BSD):
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'

" Depending on the implementation, you might need this on Windows:
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >NUL'

이들은 정중하게 단축 될 수 있습니다.

:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'

설명

:명령을 시작합니다. 명령을 입력하려면이 모드에서 일반 문자를 입력해야합니다. 스크립트에서는 생략해야합니다.

sil[ent]명령의 출력을 억제합니다. 이 경우 명령 Press any key to continue을 실행 한 후 나타나는 -like 프롬프트 를 중지하려고합니다 :!.

exec[ute]문자열을 명령으로 실행합니다. :write필요한 함수 호출을 처리하지 않기 때문에 실행할 수 없습니다 .

!:!명령을 나타냅니다 :write. 허용 하는 유일한 명령입니다 . 일반적으로 :write쓸 파일 경로를 사용합니다. :!자체적으로 쉘에서 명령을 실행합니다 (예 : 사용 bash -c). 을 사용 :write하면 셸에서 명령을 실행 한 다음 전체 파일을에 씁니다 stdin.

sudo당신이 여기에 있기 때문에 분명해야합니다. 수퍼 유저 권한으로 명령을 실행하십시오. 인터넷에는 그 작동 방식에 대한 많은 정보가 있습니다.

teestdin주어진 파일에 파이프 . :write에 쓰면 stdin수퍼 유저 tee가 파일 내용을 받아 파일을 씁니다. 내용을 덮어 쓰는 새 파일을 만들지 않으므로 파일 모드와 특성이 유지됩니다.

shellescape()주어진 파일 경로에서 현재 쉘에 적합한 특수 문자를 이스케이프합니다. 매개 변수가 하나만 있으면 일반적으로 경로를 따옴표로 묶습니다 (필요한 경우). 전체 쉘 명령 행으로 전송하기 때문에, 쉘을 넘어갈 수있는 다른 특수 문자의 백 슬래시 이스케이프를 가능하게하기 위해 0이 아닌 값을 두 번째 인수로 전달하려고합니다.

@%%현재 버퍼의 파일 이름이 포함 된 레지스터 의 내용을 읽습니다 . 반드시 절대 경로 일 필요는 없으므로 현재 디렉토리를 변경하지 않았는지 확인하십시오. 일부 솔루션에서는 상업 기호가 생략 된 것을 볼 수 있습니다. 위치에 따라 %유효한 표현식이며 %레지스터 를 읽는 것과 동일한 효과가 있습니다. 그러나 다른 식 안에 중첩되어있는 경우 바로 가기는 일반적으로 허용되지 않습니다 (예 :이 경우).

>NUL>/dev/null리디렉션 stdout플랫폼의 널 장치. 비록 우리가 명령을 침묵 시켰음에도 불구하고, stdinvim으로 다시 배관하는 것과 관련된 모든 오버 헤드를 원하지 않기 때문에 가능한 빨리 덤프하는 것이 가장 좋습니다. NULDOS, MS-DOS 및 Windows의 널 장치이며 유효한 파일이 아닙니다. Windows 8부터 NUL로 리디렉션하면 NUL이라는 파일이 작성되지 않습니다. 파일 확장자가 있거나없는 데스크탑에 NUL이라는 파일을 작성하십시오. 그렇게 할 수 없습니다. (Windows에는 알아야 할 다른 장치 이름이 몇 가지 있습니다.)

~ / .vimrc

플랫폼에 따라 다름

물론, 당신은 여전히 ​​그것들을 암기하고 매번 입력하기를 원하지 않습니다. 적절한 명령을보다 간단한 사용자 명령에 매핑하는 것이 훨씬 쉽습니다. POSIX에서이 작업을 수행하려면 ~/.vimrc파일에 다음 줄을 추가하여 파일이없는 경우 작성하십시오.

command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'

이렇게하면 : W (대소 문자 구분) 명령을 입력하여 수퍼 유저 권한으로 현재 파일을 훨씬 쉽게 작성할 수 있습니다.

플랫폼 독립적

~/.vimrc컴퓨터간에 동기화 되는 플랫폼 독립적 파일을 사용하므로 다중 플랫폼 기능을 추가했습니다. ~/.vimrc관련 설정 만있는 a 는 다음과 같습니다 .

#!vim
" Use za (not a command; the keys) in normal mode to toggle a fold.
" META_COMMENT Modeline Definition: {{{1
" vim: ts=4 sw=4 sr sts=4 fdm=marker ff=unix fenc=utf-8
"   ts:     Actual tab character stops.
"   sw:     Indentation commands shift by this much.
"   sr:     Round existing indentation when using shift commands.
"   sts:    Virtual tab stops while using tab key.
"   fdm:    Folds are manually defined in file syntax.
"   ff:     Line endings should always be <NL> (line feed #09).
"   fenc:   Should always be UTF-8; #! must be first bytes, so no BOM.


" General Commands: User Ex commands. {{{1
    command W call WriteAsSuperUser(@%)         " Write file as super-user.


" Helper Functions: Used by user Ex commands. {{{1
    function GetNullDevice() " Gets the path to the null device. {{{2
        if filewritable('/dev/null')
            return '/dev/null'
        else
            return 'NUL'
        endif
    endfunction

    function WriteAsSuperUser(file) " Write buffer to a:file as the super user (on POSIX, root). {{{2
        exec '%write !sudo tee ' . shellescape(a:file, 1) . ' >' . GetNullDevice()
    endfunction


" }}}1
" EOF

C : \ dev \ null에 실제로 쓰기 가능한 파일을 만들어 Windows를 넘어 가면 어떻게됩니까?
Paul Stelian

1
@PaulStelian 가능하지만 가능하지 않습니다. 다양한 플랫폼과 상황을 설명하기 위해이 코드를 쉽게 확장 할 수 있습니다. 실제로는 sudo존재하지만 존재하지 않는 Windows에서는 상황이 발생 하지 않을 /dev/null것이므로 진정한 크로스 플랫폼 지원을 원한다면 더 멋진 경험을해야합니다. 그것은 생각을위한 음식에 대한 소개입니다. :)
Zenexer

11

Vim을 사용하는 경우 sudo.vim 이라는 스크립트를 사용할 수 있습니다 . 루트 액세스 권한이 필요한 파일을 열었다면 다음을 입력하십시오.

: e sudo : %
Vim은 %를 현재 파일 이름으로 sudo:바꾸고 sudo.vim 스크립트가 읽고 쓸 수 있도록 지시합니다.


4
이 스크립트는 파일 이름을 이스케이프 처리하는 데 적절한 예방 조치를 취하지 않으므로 사용하지 않는 것이 좋습니다.
jamessan

7

Ryan의 조언은 일반적으로 좋지만 3 단계 이후에 임시 파일을 이동하지 마십시오. 소유권과 권한이 잘못되었습니다. 대신 sudoedit올바른 파일을 사용 :r하여 임시 파일 의 내용 (사용 등)을 읽습니다 .

2 단계 :w!를 수행하는 경우 파일을 강제로 쓰려면 사용하십시오.


3

파일에서 삽입 모드로 들어가면 편집하기 위해 sudo 액세스 권한이 필요합니다.

-- INSERT -- W10: Warning: Changing a readonly file

내가 그리워하면 일반적으로

:w ~/edited_blah.tmp
:q

..그때..

sudo "cat edited_blah.tmp > /etc/blah"

..또는..

sudo mv edited_blah.tmp /etc/blah

아마 덜 원형 교차로 방법이 있지만 작동합니다.


cat $ tmp> $ target은 창의적이지만 파일을 mv로하지 않는 이유가 있습니까?
ojrac

좋은 지적 .. 또한 sudo cat 무언가> / etc / blah에 큰 문제가있었습니다. sudo를 사용하여 파일을 고양이로 만든 다음 일반 사용자가 / etc / blah에 쓸 수 있습니다 (작동하지 않음). 대답과 더 나은 sudo mv 제안을 추가했습니다 ..
dbr

mv 제안은 권한을 유지하지 않습니다.
Paul Stelian

1

빠른 Google은 다음과 같이 조언합니다.

  1. 읽기 전용 인 경우 편집하지 마십시오.
  2. 파일에 대한 권한을 변경할 수 있습니다. (저장할 수 있는지 여부는 실험에 달려 있습니다.)
  3. 그래도 여전히 편집 한 경우 임시 파일로 저장 한 다음 이동하십시오.

http://ubuntuforums.org/showthread.php?t=782136



0

나는 ~ / .bashrc에 이것을 가지고있다 :

alias svim='sudo vim'

이제 구성 파일을 편집해야 할 때마다 svim으로 엽니 다.


2
sudoedit는 루트로 실행 정력을 필요로하지 않기 때문에 명령을 선호한다.
jamessan

2
이것은 여전히 ​​OP가 회피 한 svim 대신 vim을 묶는 것을 멈추지 않습니다.
ScaryAardvark

3
-1, 이것은 "파일을 열 때 sudo를 입력해야 함"이라고 말하고 OP는 vi 내부에서 루트 권한을 얻는 방법을 알고 싶어합니다.
Brad Koch

-2

고려할 수있는 빠른 해킹은 편집중인 파일에서 chmod를 수행하고 vim으로 저장 한 다음 chmod를 파일의 원래 상태로 되 돌리는 것입니다.

ls -l test.file (to see the permissions of the file)
chmod 777 test.file
[This is where you save in vim]
chmod xxx test.file (restore the permissions you found in the first step)

물론 보안이 걱정되는 시스템에서는이 방법을 사용하지 않는 것이 좋습니다. 몇 초 동안 누구나 모르게 파일을 읽거나 변경할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.