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 设置更改时监视并提醒用户?

相关内容