쉘이 "vi"모드 또는 "emacs"모드에있는 것은 무엇입니까?


32

이 질문 은 답변 에서 직접 이어집니다 . 이 경우 구체적으로 다음과 같은 부분을 이해할 수 없습니다.

이와 관련하여 그 동작은 bash (readline) / ksh / zsh emacs 모드보다 emacs에 더 가깝지만 Ctrl-W이전 단어를 삭제하는 터미널 드라이버 내장 라인 편집기 (표준 모드)에서 출발합니다. ).

여기서 우리는 완전히 다른 두 개의 프로그램 인 편집기가 아닌 쉘에 대해 이야기하고 있습니다. 쉘이 일부 편집기 모드에 있다는 것은 무엇을 의미합니까?

추신 : 쉘이 무엇인지 이해하고 기본 편집에 vim을 사용하는 방법을 이해한다는 전제를 바탕으로 답을 얻을 수 있습니다.


이것은 핵심 쉘 기능 자체가 아니라 라인 편집에 관한 것입니다 (오타를 작성하고 되돌아 가서 정정 할 때 수행하는 작업).
n. '대명사'm.

답변:


27

"vi"모드에서는 vi 편집기의 줄처럼 현재 쉘 프롬프트를 편집 / 탐색 할 수 있습니다. 한 줄짜리 텍스트 파일처럼 볼 수 있습니다. "emacs"모드와 유사하게 Emacs의 단축키 중 일부를 사용하여 현재 명령 행을 편집 / 탐색 할 수 있습니다.

예를 들어 vi 모드에서는 (bash에서) 다음과 같은 작업을 수행 할 수 있습니다.

$ set -o vi
$ ls hello world
<ESC>
bbdw # results in
$ ls world

emacs-mode 에서 예를 들어 Ctrl+ A를 누르면 줄의 시작 부분에서 점프 할 수 있습니다 (vi : Ctrl+ [, 0또는 ESC, 0). set -o emacsbash, ksh, zsh 등을 통해 emacs 모드를 켤 수 있습니다 .

리드 라인

bash를 포함한 많은 대화식 명령 행 프로그램 은 readline 라이브러리를 사용합니다 . 따라서 readline을 사용하는 모든 프로그램의 편집 / 탐색 인터페이스가 정확히 동일하도록 한 위치에서 사용할 입력 모드 (vi 또는 emacs) 및 기타 옵션을 구성 할 수 있습니다.

예를 들어 내 readline 구성은 다음과 같습니다.

$ cat ~/.inputrc 
set editing-mode vi
set blink-matching-paren on

예를 들어 zsh / ksh 는 내가 아는 한 readline을 사용하지 않지만 bash / readline과 매우 유사한 vi / emacs 모드를 지원합니다.

물론, 명령 행 쉘의 vi / emacs 모드는 완전한 편집기 기능 세트의 서브 세트 일뿐입니다. 모든 기능이 명령 줄 셸에서 의미있는 것은 아니며 일부 기능은 다른 기능보다 지원하기가 더 복잡합니다.

정식 모드

대화식 명령 행 쉘의 vi / emacs 모드가 '발명'되기 전에 쉘은 터미널 의 표준 모드 만 사용하여 제한된 편집 명령 세트 만 제공합니다 (예 : Ctrl+ W는 마지막 단어를 삭제합니다).


어떤 입력 모드를 사용하고 있는지 알지 못한다고 가정하십시오. 텍스트를 입력하여 확인하고 [Ctrl] + [A]를 누를 수 있습니까? 커서가 emacs의 시작으로 이동하면 vi?
limovala

2
@limovala는 근사치입니다. 셸에 따라 다릅니다. CTL + A가 작동하지 않으면 셸에 편집 모드가 포함되어 있지 않을 수도 있습니다. 아마도 일부 쉘은 다른 편집 모드를 구현할 수도 있습니다. 그러나 실제로는 방법이 충분해야합니다. 그 후에 vi 명령으로 테스트하여 더 확실하게 테스트 할 수도 있습니다. bash에서는 다음과 같은 것을 사용할 수도 있습니다 set -o | grep 'emacs\|vi'. zsh (내 vi 모드가있는 곳)에서는 작동하지 않습니다.
maxschlepzig

bind -P는 또한 어느 모드에 있는지 잘 알 수 있습니다.
Paul

23

당신은 당신이 실행할 때 것을 알 수 있습니다 cat터미널에서 쉘 프롬프트에서, cat이 표준 입력에서 읽고, 언론 무엇을 stdout에 쓰기로 생각되고 a, 당신은 볼 a터미널 드라이버로 에코 백을하지만, cat그것을 기록하지 않습니다 a당신이 볼 ( 하나만 a터미널 드라이버에 의해 반향됩니다).

그러나을 입력 a Backspace b Enter하면 cat출력 중이 a\010b\015아닌 b\012( b및 줄 바꿈)이 표시됩니다.

이는 터미널 드라이버 (터미널 에뮬레이터가 아닌 커널에서 소프트웨어를 사용하고 있음 xterm) 가 표준 모드 때 매우 기본적인 라인 편집기를 구현하기 때문 입니다. 명령을 사용할 때와 같은 시스템 호출을 사용하여 터미널 드라이버를 구성 할 수 있습니다 . 예를 들어 표준 모드를 ​​종료하려면을 수행 할 수 있습니다 . 당신이 할 경우 :ioctl()sttystty -icanon

stty -icanon; cat

그러면 echo(으로 비활성화 할 수 있음 stty -echo)과 cat출력이 동시에 표시됩니다.

그 편집기는 라인 편집기입니다. 즉, 사용자가를 누르면 터미널 장치를 읽는 응용 프로그램으로 전송 될 때까지 한 줄의 텍스트를 편집 할 수 Enter있습니다.

해당 편집기 의 편집 기능 은 매우 제한적입니다. 대부분의 구현에서는 다음과 stty같이 구성 할 수있는 편집 키 (실제 문자)는 4 개뿐입니다 .

  • 지우기 ( ^H또는 ^?보통) : 이전 문자를 지 웁니다.
  • kill (일반 ^U) : 지금까지 입력 한 줄을 비우십시오 (kill).
  • werase ( ^W) : 이전 단어를 지 웁니다.
  • ^V다음 ( ) : 문자 그대로 다음 문자를 입력하십시오 (위의 모든 문자의 특별한 의미를 취소하십시오)

예전에는 터미널 드라이버 라인 편집기가 더 멋진 기능으로 확장 될 것으로 생각되었습니다. 그렇기 때문에 초기 쉘에는 명령 행 편집 기능이 없습니다 (쉘 프롬프트에서 cat위와 같이 실행할 때와 동일한 행 편집 기능을 사용할 수 있음 ).

그러나 실제로는 결코 발생하지 않았으며, 일부 키를 눌렀을 때 다른 터미널이 같은 문자를 보내지 않는 이유는 커널 공간에서 구현해서는 안된다는 것을 분명히했습니다.

그래서 일부 쉘 은 터미널 드라이버 의 표준 모드를 삭제 하고 자체 라인 편집기를 구현 하기 시작했습니다 . 당시 emacsvi는 완전히 다른 키 바인딩 및 동작 모드와 함께 가장 인기있는 시각적 텍스트 편집기이었다. 에서 vi텍스트를 입력하는 모드와 편집을위한 모드가 하나씩 있습니다. 에서 emacs항상 텍스트 모드를 사용하고 있지만 키 조합을 누르면 편집이 수행됩니다 (예 : ^b문자를 뒤로 이동).

당시 쉘은 다른 키 바인딩을 만들 필요가 없었습니다. 그것은 사람들이 다른 것을 배우는 것에 좌절을 야기했을 것입니다. 그러나 다른 스타일보다 하나 ( emacs또는 vi) 스타일을 선택 하면 다른 편집자 의 사용자를 분리 할 수있는 확실한 방법 일 것입니다.

https://www.usenix.org/legacy/publications/library/proceedings/vhll/full_papers/korn.ksh.a 에 따르면 :

ksh의 인기있는 인라인 편집 기능 (vi 및 emacs 모드)은 Bell Laboratories의 소프트웨어 개발자가 작성했습니다. Pat Sullivan의 vi 라인 편집 모드와 Mike Veach의 emacs 라인 편집 모드. 각각은 Bourne 쉘을 독립적으로 수정하여 이러한 기능을 추가했으며 둘 다 ksh에 인라인 편집기가있는 경우에만 ksh를 사용하려는 조직에있었습니다. 원래 ksh에 명령 행 편집을 추가한다는 아이디어는 행 편집이 터미널 드라이버로 이동하기를 거부했습니다. 그러나 이것이 곧 일어나지 않을 것이 확실해 졌을 때, 두 줄 편집 모드는 모두 ksh에 통합되었고 선택적으로 만들어 터미널 인터페이스의 일부로 편집을 제공하는 시스템에서 비활성화 될 수있었습니다.

대신에 그들은 둘 다와 사용자가 둘 중 하나를 선택할 수있는 인터페이스를 구현했습니다. ksh아마 80 년대 초반 (재사용하는 VI 모드를 추가하는 별도 작성했던 코드와 위에서 볼 수 있듯이 Bourne 쉘에 이맥스 모드) 다음의 첫 번째 tcsh( tcsh처음에만 있었다 emacs키 바인딩 vi모드는 나중에 추가되었다) 이상 bash그리고 zsh90 년대 초반이다.

당신의 두 가지 모드 사이를 전환 bash, zsh또는 kshset -o viset -o emacs, 그리고와 bindkey -ebindkey -vtcshzsh.

POSIX 실제로 지정 vi모드가 아닌 emacs위한 모드 sh(이야기가있다 리차드 스톨만 (Richard Stallman)이 지정 POSIX에 반대 emacs모드를sh ).

기본 모드는 bash, 공개는 변종 ksh(pdksh 같은, mksh, oksh) tcshzsh(와 비록 이맥스 모드입니다 zsh, 그건 vi당신의 경우 $EDITORIS viAT & T에있는 동안) ksh, 그것은이다 벙어리 하지 않는 모드 $EDITOR또는 $VISUAL언급 vi하거나 emacs.

ksh또한 나중에 다르게 처리 gmacs하는 Gosling 사용자를 수용 할 수 있는 모드를 추가했습니다 .emacsCtrl+T

이제 emacs 모드 ^W에서 emacs또는 tcshemacs 모드 에서 처리하는 것이 아마도 werase터미널 라인 편집기 의 문자 보다 우선 합니다. 따라서 우리는 그 문자를 탓할 수 없으며 "departing ..." 에 대한 나의 진술은 잘못된 것으로 보일 수 있습니다. 내가 일을 좋아하는 때 자극 찾을 뿐이다 emacs, tcsh또는 info입력 할 때 다른 모든 것들과 다르게 동작합니다 Ctrl-W. 입력 할 때 일부 응용 프로그램이 창을 닫기 시작할 때 훨씬 더 짜증이 난 것을 알 수 있습니다 Ctrl-W.


1
pdksh또한 파싱 $EDITOR을 위해 vi및 시작시 모드 스위치; 나는 mksh(특히 어쨌든 실제로 Emacs 모드를 유지하기 때문에) 그것을 제거했습니다 .
mirabilos

특히 다양한 껍질의 행동과 역사에 대한 자세한 토론과 함께 추가 주셔서 감사합니다. 내가 구성하지 않은 쉘을 사용하여 다른 배포판에서 정기적으로 작업 해야하는 사람으로서 이것은 매우 도움이됩니다.
BryKKan

훌륭한 역사적 맥락에 감사드립니다. 당시에는 더 정교한 인라인 편집 기능이 터미널 드라이버에 추가되지 않은 것이 유감입니다. Readline과 같은 라이브러리를 포함하기 위해 프로그램이 필요하지 않습니다. POSIX에서 Emacs 모드를 지정하지 않은 이유가 궁금해서 이론적 근거에 대한 링크가 흥미로 웠습니다. (나는 또한 ^W창 을 닫는 것과 당신의 좌절감을 공유합니다 ).
Anthony G-

1
@AnthonyGeoghegan, 터미널 드라이버에서 파일 이름 / 명령 완성과 같은 것을 실제로 수행 할 수 없으므로 zle / readline과 같은 것이 여전히 필요합니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.