문제

종종 구성 파일을 편집하는 동안 vi로 하나를 열고 저장하려고 하면 내가 입력하지 않았다는 것을 깨닫게 됩니다.

sudo vi filename

vi에 sudo 권한을 부여하여 파일을 저장할 수 있는 방법이 있습니까?얼마 전 vi에 관한 자료를 검색하다가 이것에 대한 내용을 본 기억이 나는데 지금은 찾을 수 없습니다.

도움이 되었습니까?

해결책

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

:w !sudo tee %

(vim 파일이 변경되었음을 감지하고 다시 로드할지 여부를 묻습니다.선택하여 예라고 대답하세요. [L] 괜찮다기보다는)

바로 가기로 자신만의 명령을 정의할 수 있습니다.다음을 입력하세요. .vimrc:

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

위와 같이 입력 할 수 있습니다 :W<Enter> 파일을 저장합니다.이 글을 쓴 이후로 (내 생각에는) 이 작업을 수행하는 더 좋은 방법을 찾았습니다.

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

이런 식으로 입력할 수 있습니다. :w!! 전체 명령줄로 확장되고 커서는 끝에 남아 있으므로 % 원하는 경우 자신만의 파일 이름을 사용하세요.

다른 팁

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

:w !sudo tee myfile

일반적인 주의사항

읽기 전용 파일 문제를 해결하는 가장 일반적인 방법은 다음 구현을 사용하여 슈퍼유저로 현재 파일에 대한 파이프를 여는 것입니다. 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-실행 후 나타나는 프롬프트와 유사 :! 명령.

exec[ute] 문자열을 명령으로 실행합니다.우리는 그냥 달릴 수 없어 :write 필요한 함수 호출을 처리하지 않기 때문입니다.

! 을 나타냅니다 :! 명령:유일한 명령은 :write 받아들입니다.보통, :write 쓸 파일 경로를 허용합니다. :! 자체적으로 쉘에서 명령을 실행합니다(예: bash -c).와 함께 :write, 셸에서 명령을 실행한 다음 전체 파일을 stdin.

sudo 당신이 여기 있는 이유는 분명합니다.슈퍼유저로 명령을 실행합니다.그것이 어떻게 작동하는지에 대한 정보는 인터넷에 많이 있습니다.

tee 파이프 stdin 주어진 파일에. :write 에 쓸 것이다 stdin, 슈퍼유저 tee 파일 내용을 수신하고 파일을 작성합니다.새 파일을 생성하지 않고 내용을 덮어쓰므로 파일 모드와 속성이 유지됩니다.

shellescape() 현재 쉘에 맞게 주어진 파일 경로의 특수 문자를 이스케이프합니다.매개변수가 하나만 있으면 일반적으로 필요에 따라 경로를 따옴표로 묶습니다.전체 셸 명령줄로 보내는 것이므로 0이 아닌 값을 두 번째 인수로 전달하여 셸을 넘어갈 수 있는 다른 특수 문자의 백슬래시 이스케이프를 활성화하려고 합니다.

@% 의 내용을 읽는다 % 현재 버퍼의 파일 이름이 포함된 레지스터입니다.반드시 절대 경로일 필요는 없으므로 현재 디렉터리를 변경하지 않았는지 확인하세요.일부 솔루션에서는 commercial-at 기호가 생략된 것을 볼 수 있습니다.위치에 따라, % 유효한 표현식이며 다음을 읽는 것과 동일한 효과가 있습니다. % 등록하다.그러나 다른 표현식 내에 중첩된 단축키는 일반적으로 허용되지 않습니다.이 경우처럼 말이죠.

>NUL 그리고 >/dev/null 리디렉션 stdout 플랫폼의 null 장치에.명령을 침묵시켰음에도 불구하고 배관과 관련된 모든 오버헤드를 원하지는 않습니다. stdin vim으로 돌아가서 가능한 한 빨리 버리는 것이 가장 좋습니다. NUL DOS, 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 관련 설정만 사용:

#!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

당신이 사용하는 경우 정력, 이름이 사용 가능한 스크립트가 있습니다. sudo.vim.읽기 위해 루트 액세스가 필요한 파일을 열었다면 다음을 입력하십시오.

:e sudo:%
Vim은 %를 현재 파일 이름으로 대체합니다. sudo: sudo.vim 스크립트에 읽기 및 쓰기 작업을 맡도록 지시합니다.

Ryan의 조언은 일반적으로 좋지만 3단계를 따르는 경우 임시 파일을 이동하지 마십시오.잘못된 소유권과 권한을 가지게 됩니다.대신에, sudoedit 올바른 파일을 선택하고 내용을 읽습니다(사용 :r 등)의 임시 파일입니다.

2단계를 따르는 경우 :w! 파일을 강제로 작성합니다.

편집을 위해 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

덜 우회적인 방법이 있을 수 있지만 작동합니다.

빠른 Google은 다음과 같은 조언을 제공하는 것 같습니다.

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

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

다음은 이 질문에 대한 답변 이후 나타난 또 다른 플러그인입니다. SudoRead 및 SudoWrite 기능을 제공하는 SudoEdit라는 플러그인은 기본적으로 sudo를 먼저 사용하고 실패할 경우 su를 사용하려고 시도합니다. http://www.vim.org/scripts/script.php?script_id=2709

내 ~/.bashrc에 다음이 있습니다.

alias svim='sudo vim'

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

고려할 수 있는 빠른 해킹은 편집 중인 파일에 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)

물론 보안이 걱정되는 시스템에서는 이 접근 방식을 권장하지 않습니다. 몇 초 동안은 누구나 자신도 모르게 파일을 읽거나 변경할 수 있기 때문입니다.

사용 그쿠도 대신에 sudo GVim의 경우 즉

cmap w!! w !gksudo tee >/dev/null %
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top