據我所知,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, BoringSSL
from 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
,TERMCAP
和TERMINFO
)因此這解釋了為什麼簡單地設定TERM
為其當前值實際上會執行一個操作。
如果您無法找到它,在/TERM=${TERM}
末尾添加“”可能是一種解決方法。.profile
.bashrc
作為最後的手段,您也可以嘗試一些取證措施,如我的回答所述:當 stty 設定更改時監視並提醒用戶?