작은 Expect 스크립트를 작성하는 동안 스크립트를 실행한 후 bash 입력에 일부 문자가 자동으로 나타나는 것을 발견했습니다. 이전에 다른 프로그램에서 이런 일이 발생하는 것을 본 적이 있지만 여기에는 재현 가능한 것이 있습니다.
내 예상 스크립트는 다음과 같습니다.
#!/usr/bin/expect
spawn ssh root@[lindex $argv 0]
expect "password:"
send "[lindex $argv 1]\r"
expect "~#"
결과는 다음과 같습니다.
user@PC:~$ expect test.exp 192.168.0.2 root
spawn ssh [email protected]
[email protected]'s password:
^[[51;117Rroot@device:~# user@PC:~$ ;117R
-bash: syntax error near unexpected token `;'
user@PC:~$
출력의 다섯 번째 줄에서 볼 수 있듯이 ^[[51;117R
stdout( )에 일부 임의 문자가 있으며 그 중 일부는 셸 입력 줄( ;117R
)로 누출됩니다. Expect 스크립트를 실행한 후 Enter 키를 누르면 bash는 ( ;117R
)를 마치 bash에 입력한 것처럼 해석하려고 시도합니다.
내 질문은 여기서 무슨 일이 일어나고 있으며 이를 중지하는 방법입니다.
답변1
이것들은 모두아니요"임의의 문자".
% printf '\e[51;117R' |콘솔 디코딩 ECMA48 심폐소생술 51;117 %
원격 시스템의 로그인 프로세스 중에 실행되는 작업은 장치 상태 보고서 제어 시퀀스를 해당 터미널로 보내 해당 터미널에서 커서 위치 보고서를 요청하는 것입니다. 터미널(몇 홉 거리에 있고 ssh
DSR 출력을 통과하고 전달한 터미널 expect
)이 이를 생성하고 제 시간에 전송하고 있습니다.
% printf '\x1b[6n'' 콘솔 디코딩 ECMA48 ; ^[[30;1R 심폐소생술 30;1 만약에 %
이러한 보고서는 입력한 것과 똑같은 방식으로 터미널에서 호스트(즉, 터미널에 직접 연결된 시스템)로 전달됩니다. 호스트 시스템에서 실행 중인 프로그램이 단순히 커서 위치 보고서를 입력하고 있지 않다는 것을 알 수 있는 신뢰할 수 있는 방법은 없습니다. 물론 이 시점에서는 터미널 입력에 대한 읽기 및 전송이 없으므로 CPR은 완료 시 쉘인 expect
터미널에서 입력을 읽는 다음 프로그램에 의해 읽혀지도록 대기열에 추가됩니다 . expect
당신이 보고 있는 것은 쉘이 입력과 같은 제어 시퀀스에 어떻게 반응하는지입니다.
이는 터미널 입력 처리가 실제로 항상 적절한 상태 머신을 갖춘 적절한 ECMA-48 디코더여야 하는 이유 중 하나입니다. 쉘의 라인 편집 시스템은 그렇지 않습니다. (ZLE, Readline 또는 libedit는 실제로 터미널 입력 제어 시퀀스를 올바르게 처리하지 않습니다.) 패턴 일치를 사용하여 콘텐츠를 디코딩하는데 이는 올바른 작업을 수행하지 않습니다. 제어 시퀀스의 처음 4개 문자만 무시하는 방법에 주목하세요. 적합한 ECMA-48 입력 디코더가 디코딩됩니다.모두마지막 문자까지 모든 매개변수 문자를 포함하는 제어 시퀀스는 이를 CPR로 인식하고 (희망적으로) 쓸모 없는 입력으로 폐기합니다.
먼저 심폐소생술을 요청하려면 먼저 원격 시스템을 확인해야 하고, 터미널 로그인 시 어떤 프로그램이 실행되고 있는지 확인해야 합니다. 범인은 Xterm일 수 있습니다.resize
프로그램. (이 프로그램이 터미널이 아닐 때 Xterm을 사용하면 안 됩니다. TERM
환경 변수를 특정 xterm
유형으로 잘못 설정할 수 있기 때문입니다.) 그러나 그것이 resize
유일한 가능성은 아닙니다.
추가 읽기
- 조나단 데보인 폴라드(2018). "
console-decode-ecma48
". 스낵 가이드. 소프트웨어. - 조나단 데보인 폴라드(2019). "
TERM
". 스낵 가이드. 소프트웨어. - https://unix.stackexchange.com/a/444270/5132