etc./StackOverFlow

vim "sudo로 쓰기" 트릭은 어떻게 작동합니까?

청렴결백한 만능 재주꾼 2022. 2. 8. 08:37
반응형

질문자 :Doppelganger


많은 사람들이 sudo로 vim을 여는 것을 잊은 경우에도 루트 권한이 필요한 파일에 쓸 수 있는 명령을 보았을 것입니다.

 :w !sudo tee %

문제는 여기서 정확히 무슨 일이 일어나고 있는지 이해하지 못한다는 것입니다.

나는 이미 이것을 생각했습니다: w 는 이것에 대한 것입니다

 *:w_c* *:write_c* :[range]w[rite] [++opt] !{cmd} Execute {cmd} with [range] lines as standard input (note the space in front of the '!'). {cmd} is executed like with ":!{cmd}", any '!' is replaced with the previous command |:!|.

따라서 모든 라인을 표준 입력으로 전달합니다.

!sudo tee 부분은 관리자 권한으로 tee

모두 이해하려면 % 가 파일 이름을 출력해야 합니다( tee 대한 매개변수). 하지만 이 동작에 대한 도움말에서 참조를 찾을 수 없습니다.

tl;dr 누군가 이 명령을 분석하는 데 도움을 줄 수 있습니까?



In :w !sudo tee % ...

% 는 "현재 파일"을 의미합니다.

eugene y가 지적했듯이 % 는 실제로 "현재 파일 이름"을 의미하며 어떤 파일을 덮어쓸지 알 수 있도록 tee

(대체 명령에서는 약간 다릅니다. :help :% 표시하는 것처럼 equal to 1,$ (the entire file) (이가 파일 이름으로 평가되지 않는다는 점을 지적한 @Orafu 덕분에). 예를 들어 :%s/foo/bar 수단 "현재 파일의 발생 대체 foo 함께 bar ."당신이 입력하기 전에 텍스트 강조하는 경우 :s , 당신은 강조 라인의 장소 걸릴 것을 볼 수 있습니다 % 귀하의 대체 범위로).

:w 는 파일을 업데이트하지 않습니다

이 트릭의 한 가지 혼란스러운 부분은 :w 가 파일을 수정하고 있다고 생각할 수 있지만 그렇지 않다는 것입니다. file1.txt 를 열고 수정한 다음 :w file2.txt 를 실행했다면 "다른 이름으로 저장"이 됩니다. file1.txt 는 수정되지 않지만 현재 버퍼 내용은 file2.txt 로 전송됩니다.

file2.txt 대신 셸 명령을 사용하여 버퍼 내용을 받을 수 있습니다 . 예를 들어 :w !cat 은 내용만 표시합니다.

Vim이 sudo 액세스로 실행되지 않은 경우 :w 는 보호된 파일을 수정할 수 없지만 버퍼 내용을 셸에 전달하면 셸 의 명령을 sudo로 실행할 있습니다. 이 경우 tee 를 사용합니다.

티 이해하기

tee 경우 tee 명령을 일반적인 bash 파이핑 상황에서 T자형 파이프로 상상해 보십시오. 지정된 파일로 출력을 보내고 다음 파이프된 명령으로 캡처할 수 있는 표준 출력으로도 보냅니다.

예를 들어, ps -ax | tee processes.txt | grep 'foo' 프로세스 목록은 텍스트 파일에 기록에 전달됩니다 grep .

 +-----------+ tee +------------+ | | -------- | | | ps -ax | -------- | grep 'foo' | | | || | | +-----------+ || +------------+ || +---------------+ | | | processes.txt | | | +---------------+

(Asciiflow로 만든 다이어그램 .)

자세한 내용은 tee man 페이지 를 참조하십시오.

해킹으로 티

귀하의 질문에 설명된 상황에서 tee 를 사용하는 것은 그것이 하는 일의 절반을 무시하기 때문에 해킹 입니다. sudo tee 는 파일에 쓰고 버퍼 내용도 표준 출력으로 보내지만 표준 출력은 무시합니다 . 이 경우 다른 파이프된 명령에 아무 것도 전달할 필요가 없습니다. 우리는 파일을 작성하는 대체 방법으로 tee sudo 호출할 수 있습니다.

이 트릭을 쉽게 만들기

당신은 당신이를 추가 할 수 .vimrc 사용하기 쉬운이 트릭을 만들 : 단지 유형 :w!! .

 " Allow saving of files as sudo when I forgot to start vim using sudo. cmap w!! w !sudo tee > /dev/null %

> /dev/null 부분은 내가 말했듯이 파이프로 연결된 다른 명령에 아무 것도 전달할 필요가 없기 때문에 표준 출력을 명시적으로 버립니다.


Nathan Long

실행된 명령줄에서 % 는 현재 파일 이름을 나타냅니다. :help cmdline-special 문서화되어 있습니다.

 In Ex commands, at places where a file name can be used, the following characters have a special meaning. % Is replaced with the current file name.

이미 알고 있듯이 :w !cmd 는 현재 버퍼의 내용을 다른 명령으로 파이프합니다. tee 가 하는 일은 표준 입력을 하나 이상의 파일과 표준 출력에 복사하는 것입니다. 따라서 :w !sudo tee % > /dev/null 은 root 인 동안 현재 버퍼의 내용을 현재 파일에 효과적으로 씁니다. 이를 위해 사용할 수 있는 또 다른 명령은 dd .

 :w !sudo dd of=% > /dev/null

바로 가기로 이 매핑을 .vimrc 추가할 수 있습니다.

 " Force saving files that require root permission cnoremap w!! w !sudo tee > /dev/null %

위와 같이 :w!!<Enter> 를 입력하여 파일을 루트로 저장할 수 있습니다.


Eugene Yarmash

:w - 파일을 씁니다.

!sudo - 쉘 sudo 명령을 호출합니다.

tee 사용하여 리디렉션된 쓰기(vim :w) 명령의 출력입니다. %는 현재 파일 이름(예: /etc/apache2/conf.d/mediawiki.conf)일 뿐입니다. 즉, tee 명령은 루트로 실행되고 표준 입력을 받아 %로 표시되는 파일에 씁니다. 그러나 파일을 다시 로드하라는 메시지가 표시됩니다(vim 자체의 변경 사항을 로드하려면 L 키를 누르십시오).

튜토리얼 링크


kev

이것은 또한 잘 작동합니다:

 :w !sudo sh -c "cat > %"

이것은 @Nathan Long의 의견에서 영감을 받았습니다.

고시 :

쉘에 전달하기 전에 % 가 확장되기를 원하기 때문에 ' 대신에 "


feihu

허용되는 답변은 모든 것을 다루므로 기록을 위해 사용 하는 바로 가기의 또 다른 예를 보여 드리겠습니다.

etc/vim/vimrc (또는 ~/.vimrc )에 추가하십시오.

  • cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' <bar> edit!

어디에:

  • cnoremap : 다음 단축키가 명령줄에 연결되어야 함을 vim에 알립니다.
  • w!! : 바로 가기 자체.
  • execute '...' : 다음 문자열을 실행하는 명령.
  • silent! : 조용히 실행
  • write !sudo tee % >/dev/null : OP 질문, 깨끗한 명령을 만들기 NULL
  • <bar> edit! : 이 트릭은 케이크의 핵심입니다. 버퍼를 다시 로드한 다음 버퍼가 변경 edit 명령도 호출합니다. <bar> 는 여기에서 두 개의 명령을 구분하기 위해 파이프 기호를 작성하는 방법입니다.

도움이 되기를 바랍니다. 다른 문제도 참조하십시오.


DrBeco

"죄송합니다. 내 파일을 여는 동안 sudo 를 작성하는 것을 잊었습니다" 문제에 대한 다른 접근 방식을 제안하고 싶습니다.

permission denied 되고 입력해야 하는 대신 :w!! , 파일 소유자가 root sudo vim vim 명령을 사용하는 것이 더 우아하다는 것을 알았습니다.

이것은 구현하기 쉽습니다 (더 우아한 구현이있을 수 있습니다. 나는 분명히 bash-guru가 아닙니다).

 function vim(){ OWNER=$(stat -c '%U' $1) if [[ "$OWNER" == "root" ]]; then sudo /usr/bin/vim $*; else /usr/bin/vim $*; fi }

그리고 그것은 정말 잘 작동합니다.

이것은 vim bash 중심의 접근 방식이므로 모든 사람이 좋아하지 않을 수 있습니다.

물론이야:

  • 실패하는 사용 사례가 있습니다(파일 소유자가 root sudo 가 필요하지만 기능은 어쨌든 편집할 수 있는 경우)
  • vim 을 파일 읽기 전용으로 사용할 때는 의미가 없습니다(제가 생각하는 한 작은 파일 tail 또는 cat

bash 를 사용할 때 IMHO가 잊어버리는 경향이 있는 훨씬 더 나은 개발 사용자 경험을 제공한다는 것을 알았습니다. :-)


Augustin Riedinger

네오빔을 위해

대화식 호출 문제( https://github.com/neovim/neovim/issues/1716 )로 인해 Dr Beco의 답변에 따라 neovim에 이것을 사용하고 있습니다.

 cnoremap w!! execute 'silent! write !SUDO_ASKPASS=`which ssh-askpass` sudo tee % >/dev/null' <bar> edit!

ssh-askpass 를 사용하여 sudo 암호를 묻는 대화 상자가 열립니다.


dbranco

2020년 현재 이에 대해 찾은 가장 일반적인 답변에 대한 요약(및 매우 사소한 개선)입니다.

헐 박사

전화주세요 :w!! 또는 :W!! . 이 확장 한 후 Enter 키를 눌러 enter .

  • 타이핑이 너무 느리다면 !! w/W 후에 확장되지 않고 다음을 보고할 수 있습니다. E492: Not an editor command: W!!

참고 사용자의 경우에 다른 경우 /usr/bin/tee 를 대체할 which tee 출력을 사용하십시오.

~/.vimrc 파일에 넣으세요.

 " Silent version of the super user edit, sudo tee trick. cnoremap W!! execute 'silent! write !sudo /usr/bin/tee "%" >/dev/null' <bar> edit! " Talkative version of the super user edit, sudo tee trick. cmap w!! w !sudo /usr/bin/tee >/dev/null "%"

더 많은 정보:

첫째, 아래 링크된 답변은 가장 알려진 문제를 완화하고 다른 문제와 상당한 차이가 있는 것으로 보이는 유일한 다른 답변에 관한 것입니다. 읽을 가치: https://stackoverflow.com/a/12870763/2927555

위의 내 답변은 기존의 sudo tee 테마에 대한 여러 제안에서 함께 가져왔으므로 내가 찾은 가장 일반적인 답변을 약간 개선했습니다. 위의 내 버전:

  • 파일 이름의 공백과 함께 작동

  • 티에 대한 전체 경로를 지정하여 경로 수정 공격을 완화합니다.

  • 두 개의 매핑을 제공합니다. W!! 자동 실행 및 w!! 침묵하지 않기 위해, 즉 수다스러운 :-)

  • 무음 버전을 사용할 때의 차이점은 [O]k와 [L]load 중에서 선택할 수 있다는 것입니다. 상관없다면 무음 버전을 사용하세요.

    • [O]k - 실행 취소 기록을 보존하지만 종료하려고 할 때 경고를 받게 됩니다. 당신은 사용해야합니다 :q! 종료합니다.
    • [로드] 로드 - 실행 취소 기록을 지우고 변경 사항을 저장하라는 경고 없이 종료할 수 있도록 "수정된 플래그"를 재설정합니다.

위의 정보는 이에 대한 많은 다른 답변과 의견에서 가져온 것이지만 특히 다음과 같습니다.

Beco 박사의 답변: https://stackoverflow.com/a/48237738/2927555

이에 대한 idbrii의 의견: https://stackoverflow.com/a/25010815/2927555

이에 대한 Han Seoul-Oh의 의견: vim "write with sudo" 트릭은 어떻게 작동합니까?

이에 대한 Bruno Bronosky 의견: https://serverfault.com/a/22576/195239

이 답변은 또한 가장 단순한 접근 방식이 좋은 생각이 아닌 이유를 설명합니다. https://serverfault.com/a/26334/195239


Chris

cnoremap w!! 의 유일한 문제!! w 로 대체한다는 것 ! (그리고 다음 문자를 입력할 때까지 중단됨) w! : 명령 프롬프트에서. w! 강제 저장하고 싶을 때처럼! . 또한 다음의 첫 번째 항목이 아니더라도 : .

<Fn>w 와 같은 것으로 매핑하는 것이 좋습니다. 저는 개인적으로 메이플레이더 = F1 을 가지고 있으므로 <Leader>w 있습니다.


usretc

출처 : http:www.stackoverflow.com/questions/2600783/how-does-the-vim-write-with-sudo-trick-work

반응형