SSH 이스케이프 키("~")는 연결이 중단된 경우에만 작동합니까?

SSH 이스케이프 키("~")는 연결이 중단된 경우에만 작동합니까?

응답하지 않는 SSH 연결이 있으면 <enter>~.. 그러나 연결이 응답하면 ~이스케이프가 작동하지 않습니다. 콘솔에 틸다만 인쇄합니다.

따라서 SSH 포트 전달을 수정하고 를 누르면 <enter>~C<enter>다음과 같은 결과가 나옵니다.

~C: command not found

( 에서 bash가 아니라 에서 ssh.)

SSH 이스케이프 키가 제대로 작동하려면 어떻게 해야 합니까?

편집하다:나는 큰 단서를 찾았습니다. 원격 쉘은 실제로 ash가 아니라 였습니다 bash. 원격 컴퓨터에서 실행하면 bashSSH 이스케이프 키가 작동합니다! ash내부로 bash실행 하면 ash다시 작동하지 않습니다!

그러나 이것은 매우 이상합니다. 이스케이프 키는 SSH 클라이언트에 의해 포착되어야 하며 원격 셸로 전달되지도 않아야 합니다. 그렇다면 SSH로부터 입력을 받는 원격 쉘이 정확히 무엇인지가 왜 중요한가요?

답변1

간단한 해결 방법: cat명령을 실행한 다음 이스케이프 시퀀스를 입력합니다.

cat명령은 기본적으로 전달된 내용을 인쇄하므로 stdin실행 중에는 이스케이프 문자가 전송되지 않으며 SSH 이스케이프 키를 정상적으로 사용할 수 있습니다. 완료되면 쉘로 돌아갑니다 ctrl-c.cat

필요한 경우 프롬프트를 열고 Enter cat키를 눌러 실행합니다 cat.

$ 
$ cat 

이제 ~?를 입력하세요.

~?
Supported escape sequences:
 ~.   - terminate connection (and any multiplexed sessions)
 ~B   - send a BREAK to the remote system
 ~C   - open a command line
 ~R   - request rekey
 ~V/v - decrease/increase verbosity (LogLevel)
 ~^Z  - suspend ssh
 ~#   - list forwarded connections
 ~&   - background ssh (when waiting for connections to terminate)
 ~?   - this message
 ~~   - send the escape character by typing it twice

효과가있다! 이제 아무 명령이나 입력하면 됩니다. 그런 다음 프롬프트로 돌아가려면 Ctrl-C를 누르세요.

^C
$

답변2

비밀을 알아냈어요!

위의 "편집"에 게시한 것처럼 원격 셸은 BusyBox 가 ash아니라 입니다 bash.

libbb/lineedit.c:2336-2338BusyBox 소스에서 :

/* Print out the command prompt, optionally ask where cursor is */
parse_and_put_prompt(prompt);
ask_terminal();

NET에서 명령 프롬프트를 인쇄하는 데 사용됩니다 ash. 그러나 프롬프트를 인쇄하자마자 호출되는 또 다른 함수가 ask_terminal호출됩니다. 무엇을 ask_terminal합니까? 다음 문자를 인쇄합니다: <ESCAPE>[6n.

터미널에서는 해당 문자를 볼 수 없습니다. 실제로 이는 ANSI 터미널 제어 이스케이프 코드입니다. <ESC>[6n"Query Cursor Position" 명령입니다. 이는 터미널 창에서 커서(텍스트 삽입 지점)가 있는 위치를 쉘에 알려주는 또 다른 ANSI 이스케이프 코드를 다시 보내도록 터미널 에뮬레이터에 지시합니다.

따라서 을 누르 Enter자마자 ash을 인쇄 <ESC>[6n하고 터미널 에뮬레이터로 sshd다시 전달합니다 . ssh을 누르기 직전에 ~터미널 에뮬레이터는 <ESC>[47;13R표준 입력과 같은 내용을 보내고 ssh연결을 통해 로 전달 sshd하고 커서 위치를 ash알려줍니다 .ash

이제 SSH 클라이언트는 실제로 ANSI 이스케이프 코드가 무엇을 의미하는지 알지 못합니다. SSH의 경우 이는 모두 표준 입력에서 읽은 문자일 뿐입니다. <ENTER>~CSSH 클라이언트는 을 보는 대신 을 보고, 바로 뒤에는 <ENTER><ESC>[47;13R~C보지 않기 때문에 이스케이프 코드라고 생각하지 않습니다.~Enter

문제는 이에 대해 어떻게 해야 하느냐는 것입니다. OpenSSH가 터미널에서 보낸 ANSI 이스케이프를 이해하고 ~ANSI 터미널 제어 명령 이후에도 이스케이프 문자를 허용한다면 좋을 것입니다 . OpenSSH 담당자에게 패치를 보내고 그들이 이 문제를 해결하는 데 관심이 있는지 알아볼 수 있습니다.

답변3

당신은 물었습니다확실히 SSH 클라이언트 이스케이프 키는 이렇게 작동하지 않습니까 ??

예, 다음과 같이 작동해야 합니다.

Enter다음을 누르면 이스케이프가 실행되는 프롬프트에 ~문자가 표시되지 않습니다 .~ssh

다시 누르면 ~프롬프트에 나타나고 작업 쉘(예에서는 bash)에서 작동하여 다음을 시도합니다.확장하다알고 있는 대로 사용하세요.

일하려면 ~가장 먼저 해야 한다는 점에 유의하세요.라인 버퍼, 따라서 아무 문자나 입력하고 모든 줄을 지운 후에는 더 이상 해당 줄이 없습니다.새로운다시 눌러야합니다 Enter.

내가 누르면 ~?나는 얻는다

지원되는 이스케이프 시퀀스:
~. - 연결(및 멀티플렉싱된 세션) 종료
~B - 원격 시스템에 BREAK 보내기
~C - 명령줄 열기
~R - 키 재설정 요청(SSH 프로토콜 2만 해당)
~^Z - SSH 일시 중지
~# - 전달된 연결 목록
~ & - 백그라운드 SSH(연결 종료를 기다리는 경우)
~? - 이 메시지
~~ - 이스케이프 문자를 두 번 입력하여 전송합니다.
(이스케이프는 줄 바꿈 직후에만 인식된다는 점에 유의하세요.)

관련 정보