많은 사람들이 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 누군가 내가이 명령을 분석하도록 도와 줄 수 있습니까?
답변
에서 :w !sudo tee %
…
%
“현재 파일”을 의미
으로 유진 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
통상 배시 배관 상황에서 T 자관과 같은 명령을 : 그것은 지정된 파일 (들)에 출력을 지시하고 또한 표준 출력에 보낼 다음 파이프 명령에 의해 포착 될 수있다.
예를 들어에서에서 ps -ax | tee processes.txt | grep 'foo'
프로세스 목록은 텍스트 파일에 기록 되고에 전달됩니다 grep
.
+-----------+ tee +------------+
| | -------- | |
| ps -ax | -------- | grep 'foo' |
| | || | |
+-----------+ || +------------+
||
+---------------+
| |
| processes.txt |
| |
+---------------+
( Asciiflow로 만든 다이어그램 )
자세한 내용은 tee
매뉴얼 페이지 를 참조하십시오.
해킹으로 티
귀하의 질문에 설명 된 상황에서 사용 tee
하는 것은 우리가하는 일의 절반을 무시하기 때문에 해킹 입니다. sudo tee
파일에 쓰고 버퍼 내용을 표준 출력으로 보내지 만 표준 출력은 무시합니다 . 이 경우 다른 파이프 명령에 아무것도 전달할 필요가 없습니다. 우리는 tee
파일을 작성하는 다른 방법으로 사용 하고 있으며로 호출 할 수 있습니다 sudo
.
이 트릭을 쉽게 만들기
이것을 .vimrc
사용 하여이 트릭을 사용하기 쉽게 만들 수 있습니다 : 그냥 type :w!!
.
" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! w !sudo tee > /dev/null %
> /dev/null
부분은 명시 적으로 내가 말했듯이, 우리가 다른 파이프 명령에 아무것도 통과 할 필요가 없습니다, 때문에, 표준 출력을 버린다.
답변
실행 된 명령 행 %
에서 현재 파일 이름을 나타냅니다 . 이 내용은 다음과 :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
일은 표준 출력에 하나 개 이상의 파일을 표준 입력을 복사합니다. 따라서 root 인 동안:w !sudo tee % > /dev/null
현재 버퍼의 내용을 현재 파일에 효과적으로 씁니다 . 이를 위해 사용할 수있는 다른 명령은 다음과 같습니다.dd
:w !sudo dd of=% > /dev/null
바로 가기로이 매핑을 다음에 추가 할 수 있습니다 .vimrc
.
" Force saving files that require root permission
cnoremap w!! w !sudo tee > /dev/null %
위와 같이 입력 :w!!<Enter>
하면 파일을 루트로 저장할 수 있습니다 .
답변
이것은 또한 잘 작동합니다 :
:w !sudo sh -c "cat > %"
이것은 @Nathan Long의 의견에서 영감을 얻었습니다.
공지 사항 :
"
쉘로 전달하기 전에 확장 '
되기를 원 %
하기 때문에 대신 사용해야합니다 .
답변
:w
-파일을 작성하십시오.
!sudo
-쉘 sudo 명령을 호출하십시오.
tee
-tee를 사용하여 재 지정된 쓰기 (vim : w) 명령의 출력. %는 현재 파일 이름, 즉 /etc/apache2/conf.d/mediawiki.conf입니다. 즉, tee 명령은 루트로 실행되며 표준 입력을 사용하여 %로 표시되는 파일에 씁니다. 그러나 파일을 다시로드하라는 메시지가 표시됩니다 (vim 자체에 변경 사항을로드하려면 L을 누르십시오).
답변
허용 된 답변은 모든 것을 다루므로 레코드에 사용 하는 바로 가기 의 또 다른 예를 제공 합니다.
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>
를 작성하여 두 명령을 분리 하는 방법 입니다.
도움이 되길 바랍니다. 다른 문제도 참조하십시오 :
답변
” sudo
파일을 여는 동안 쓰기 를 잊어 버린 Oups “ 문제 에 대한 또 다른 접근 방식을 제안하고 싶습니다 .
을 수신하고 permission denied
입력 하는 대신 파일 소유자가 :w!!
조건부 vim
명령을 수행 하는 것이 더 우아하다는 것을 알았습니다 .sudo vim
root
이것은 구현하기 쉽습니다 (더 우아한 구현이있을 수 있습니다. 나는 분명히 bash-guru가 아닙니다).
function vim(){
OWNER=$(stat -c '%U' $1)
if [[ "$OWNER" == "root" ]]; then
sudo /usr/bin/vim $*;
else
/usr/bin/vim $*;
fi
}
그리고 그것은 정말 잘 작동합니다.
이것은 하나보다 더 bash
중심적인 접근 방식 vim
이므로 모든 사람이 좋아할 수는 없습니다.
물론이야:
- 실패 할 유스 케이스가 있습니다 (파일 소유자가
root
아니지만 필요sudo
하지만 함수를 편집 할 수있는 경우) vim
파일을 읽기 전용으로 사용할 때는 의미가 없습니다 (관심있는 한, 사용tail
하거나cat
작은 파일)
그러나 이것은 훨씬 더 나은 개발 사용자 경험을 가져다 주며 , 이는 IMHO를 사용할 때 잊어 버리는 경향이 있습니다 bash
. 🙂
답변
네오 빔
대화 형 호출 ( https://github.com/neovim/neovim/issues/1716 )의 문제로 인해 Beco 박사의 답변에 따라 네오 빔에 이것을 사용하고 있습니다.
cnoremap w!! execute 'silent! write !SUDO_ASKPASS=`which ssh-askpass` sudo tee % >/dev/null' <bar> edit!
ssh-askpass
sudo 암호 를 묻는 대화 상자가 열립니다 .