질문자 :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 암호를 묻는 대화 상자가 열립니다.
dbranco2020년 현재 이에 대해 찾은 가장 일반적인 답변에 대한 요약(및 매우 사소한 개선)입니다.
헐 박사
전화주세요 :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
Chriscnoremap 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