ssh 退格鍵無法運作,直到我手動執行 TERM=xterm

ssh 退格鍵無法運作,直到我手動執行 TERM=xterm

據我所知,ssh如果TERM設定不正確,退格鍵現在可能會在會話中工作。但奇怪的是,我有一個伺服器TERM設定正確,但退格鍵不起作用,直到我TERM=xterm在 shell 中手動設定(這應該是多餘的)。看這裡:

~ ] ssh [email protected]
root 192.168.10.40 / # echo $0
-bash
root 192.168.10.40 / # echo $TERM
xterm-256color
root 192.168.10.40 / #     # backspace does not work :(
root 192.168.10.40 / # 
root 192.168.10.40 / # TERM=xterm-256color
root 192.168.10.40 / # # now backspace works!!
root 192.168.10.40 / # logout

我想說,大約 90% 的情況下,退格鍵在運行之前不會起作用TERM=xterm,而 10% 的情況下,我不需要運行該TERM=命令,因為退格鍵已經起作用了。我比較了env每種情況的輸出,它們是相同的(除了SSH_CLIENT並且SSH_CONNECTION只有客戶端連接埠發生了變化)

知道什麼可能導致這種行為,或解決方法可能是什麼?


對評論的回應

我正在使用OpenSSH_6.8p1, BoringSSLfrom https://android.googlesource.com/platform/external/openssh,並且我正在運行GNU bash, version 4.3.42(1)-release (arm-android-eabi)fromhttps://github.com/CyanogenMod/android_external_bash.git

stty -a顯示設定前後沒有什麼不同XTERM。輸出是:

speed 38400 baud; rows 102; columns 319; line = 2;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

bind -p|egrep 'delete|rubout|kill'也顯示設定前後沒有什麼不同XTERM。輸出是:

"\C-h": backward-delete-char
"\C-?": backward-delete-char
"\C-x\C-?": backward-kill-line
"\e\C-h": backward-kill-word
"\e\C-?": backward-kill-word
# copy-region-as-kill (not bound)
"\C-d": delete-char
"\e[3~": delete-char
# delete-char-or-list (not bound)
"\e\\": delete-horizontal-space
# forward-backward-delete-char (not bound)
"\C-k": kill-line
# kill-region (not bound)
# kill-whole-line (not bound)
"\ed": kill-word
# shell-backward-kill-word (not bound)
# shell-kill-word (not bound)
# unix-filename-rubout (not bound)
"\C-w": unix-word-rubout
# vi-delete (not bound)
# vi-delete-to (not bound)
# vi-overstrike-delete (not bound)
# vi-rubout (not bound)

有趣的是,如果我source按下bashrc,我的退格鍵將再次開始工作。我知道它是在登入時取得的,因為這是我設定值bashrc的唯一地方Ps1

答案1

看起來像 readline/終端交互,首先在登入過程中檢查您的.inputrc, /etc/inputrc, /etc/default/login,INPUTRC環境變量,然後 readline 綁定(通過bind -q backward-delete-char)。

仔細檢查客戶端 (ssh_config)SendEnv和伺服器 (sshd_config AcceptEnv) 指令中的內容也沒有什麼壞處,如果有的話(儘管TERM在 OpenSSH 中不是以這種方式從客戶端發送到伺服器,客戶端始終TERM在會話設定中包含該值,並且伺服器設定TERM從此)。我能想到的唯一可以解釋這種現象間歇性的原因是環境中TERMINFO的偶爾存在。TERMCAP

Readline 將「rubout」套用於終端聲明其「擦除」的任何內容,而 rubout 是 readline 透過 呼叫的內容backward-delete-char

TERM是 bash 監視的特殊變數之一,當它被設定時(與它是否變化bash 重置終端:

/* What to do just after one of the TERMxxx variables has changed.
   If we are an interactive shell, then try to reset the terminal
   information in readline. */
void
sv_terminal (name)
     char *name;
{
  if (interactive_shell && no_line_editing == 0)
    rl_reset_terminal (get_string_value ("TERM"));
}

(其中“ TERMxxx”表示TERM,TERMCAPTERMINFO)因此這解釋了為什麼簡單地設定TERM為其當前值實際上會執行一個操作。

如果您無法找到它,在/TERM=${TERM}末尾添加“”可能是一種解決方法。.profile.bashrc

作為最後的手段,您也可以嘗試一些取證措施,如我的回答所述:當 stty 設定更改時監視並提醒用戶?

相關內容