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