Bash

將字元洩漏到 bash 的命令

  • February 6, 2019

在建構一個小的期望腳本時,我注意到在執行腳本後,一些字元會自動出現在 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 root@192.168.0.2
root@192.168.0.2's password:

^[[51;117Rroot@device:~# user@PC:~$ ;117R
-bash: syntax error near unexpected token `;'
user@PC:~$

所以你可以在輸出的第五行看到,stdout ( ^[[51;117R) 上有一些隨機字元,其中一些洩漏到 shell 輸入行 ( ;117R)。如果我在執行期望腳本後按輸入鍵,bash 會嘗試解釋該 ( ;117R),就好像我已將它輸入到 bash 中一樣。

我的問題是,這裡發生了什麼,我該如何阻止它?

這些不是“隨機字元”。

% printf '\e[51;117R' | 控制台解碼 ecma48
心肺復蘇術 51;117
%

在遠端系統的登錄過程中執行的東西是,通過向其終端發送設備狀態報告控制序列,從該終端請求游標位置報告。終端(您的終端,在幾跳之外,通過ssh和傳遞了 DSR 輸出expect)正在適當地生成和發送它。

% printf '\x1b[6n' ; 控制台解碼 ecma48
^[[30;1R
心肺復蘇術 30;1
如果
%

這種報告從終端到達主機(即直接連接到終端的機器)的方式與鍵入輸入的方式完全相同。在主機上執行的程序沒有可靠的方法知道您沒有簡單地鍵入游標位置報告。當然expect此時不是在終端輸入上讀取和發送,因此 CPR 已排隊等待下一個從終端讀取輸入的程序讀取,這是expect完成後的外殼。您所看到的是您的 shell 如何對輸入等控制序列做出反應。

這些事情是終端輸入處理應該始終是具有適當狀態機的適當 ECMA-48 解碼器的原因之一。你的 shell 的行編輯系統不是。(ZLE、Readline 或 libedit 都沒有真正正確地處理終端輸入控制序列。)它正在使用模式匹配對事物進行解碼,這並沒有做正確的事情。注意它是如何只忽略控制序列的前四個字元的。一個合適的 ECMA-48 輸入解碼器將解碼整個控制序列,包括所有參數字元直到最終字元,將其辨識為 CPR,並且(希望)將其作為沒有用的輸入丟棄。

至於首先請求 CPR 的內容:為此,您必須檢查遠端系統,以及它在終端登錄時執行的程序。一個可能的罪魁禍首是 Xtermresize程序。(請注意,當 Xterm 不是您的終端時,您不應使用該程序,因為它會錯誤地將TERM環境變數設置為一種xterm類型。)但這resize不是唯一的可能性。

進一步閱讀

引用自:https://unix.stackexchange.com/questions/499086