zsh 中的 Home/End 键不适用于 putty
Posted
技术标签:
【中文标题】zsh 中的 Home/End 键不适用于 putty【英文标题】:Home/End keys in zsh don't work with putty 【发布时间】:2010-09-14 18:29:15 【问题描述】:我在 Ubuntu 机器上将 zsh 作为默认 shell 运行,并且使用 gnome-terminal(据我所知模拟 xterm)一切正常。当我通过 ssh 和 putty(也模拟 xterm)从 windows 框登录时,突然 home/end 键不再起作用。
我已经能够解决将这些行添加到我的 zshrc 文件中的问题...
bindkey '\e[1~' beginning-of-line
bindkey '\e[4~' end-of-line
...但我仍然想知道这里出了什么问题。有什么想法吗?
【问题讨论】:
感谢以上绑定。现在在 SecurtCRT 为我工作 感谢您的命令。对我来说,这个设置有效:bindkey '^[OH' beginning-of-line
和 bindkey '^[OF' end-of-line
。
【参考方案1】:
我发现这是一个组合:
一个
ZSH 开发者认为 ZSH 不应该定义 Home、End、Del、...键的动作。
Debian 和 Ubuntu 通过在全局 /etc/zsh/zshrc
文件中定义普通用户期望的正常操作来解决此问题。按照相关代码(在Debian和Ubuntu上相同):
if [[ "$TERM" != emacs ]]; then
[[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
[[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
[[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line
[[ -z "$terminfo[kich1]" ]] || bindkey -M emacs "$terminfo[kich1]" overwrite-mode
[[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
[[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
[[ -z "$terminfo[kend]" ]] || bindkey -M vicmd "$terminfo[kend]" vi-end-of-line
[[ -z "$terminfo[kich1]" ]] || bindkey -M vicmd "$terminfo[kich1]" overwrite-mode
[[ -z "$terminfo[cuu1]" ]] || bindkey -M viins "$terminfo[cuu1]" vi-up-line-or-history
[[ -z "$terminfo[cuf1]" ]] || bindkey -M viins "$terminfo[cuf1]" vi-forward-char
[[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
[[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
[[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
[[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
# ncurses fogyatekos
[[ "$terminfo[kcuu1]" == "^[O"* ]] && bindkey -M viins "$terminfo[kcuu1]/O/[" vi-up-line-or-history
[[ "$terminfo[kcud1]" == "^[O"* ]] && bindkey -M viins "$terminfo[kcud1]/O/[" vi-down-line-or-history
[[ "$terminfo[kcuf1]" == "^[O"* ]] && bindkey -M viins "$terminfo[kcuf1]/O/[" vi-forward-char
[[ "$terminfo[kcub1]" == "^[O"* ]] && bindkey -M viins "$terminfo[kcub1]/O/[" vi-backward-char
[[ "$terminfo[khome]" == "^[O"* ]] && bindkey -M viins "$terminfo[khome]/O/[" beginning-of-line
[[ "$terminfo[kend]" == "^[O"* ]] && bindkey -M viins "$terminfo[kend]/O/[" end-of-line
[[ "$terminfo[khome]" == "^[O"* ]] && bindkey -M emacs "$terminfo[khome]/O/[" beginning-of-line
[[ "$terminfo[kend]" == "^[O"* ]] && bindkey -M emacs "$terminfo[kend]/O/[" end-of-line
fi
因此,如果您连接到 Debian 或 Ubuntu 机器,您无需执行任何操作。一切都应该自动运行(如果不是,请参见下文)。
但是...如果您连接到另一个机器(例如 FreeBSD),则可能没有用户友好的默认 zshrc
。解决方案当然是将 Debian/Ubuntu zshrc
中的行添加到您自己的 .zshrc
中。
两个
Putty 将xterm
作为终端类型发送到远程主机。但是在某处搞砸了,并且没有为 Home、End 发送正确的控制代码,......这是人们对xterm
的期望。或者xterm
终端不应该发送这些或任何东西......(Del 键在xterm
中确实有效,但是,如果你在 ZSH 中配置它)。另请注意,您的小键盘键在 Vim 中的行为很有趣,例如使用 xterm
终端。
解决方法是配置Putty发送另一种终端类型。我试过xterm-color
和linux
。 xterm-color
修复了 Home/End 问题,但小键盘仍然很有趣。将其设置为 linux
解决了这两个问题。
您可以在连接 -> 数据下的 Putty 中设置终端类型。不要试图用export TERM=linux
在.zshrc
中设置终端类型,这是错误的。终端类型应由您的终端应用程序指定。因此,例如,如果您从带有 Mac SSH 客户端的 Mac 机器进行连接,它可以设置自己的终端类型。
请注意,TERM 指定您的终端类型,与您要连接的主机无关。我可以在 Putty 中将终端类型设置为 linux
并毫无问题地连接到 FreeBSD 服务器。
所以,解决这两个问题,你应该会没事的 :)
【讨论】:
修复有趣的键盘行为的另一种方法:打开会话设置,转到Terminal -> Features
并选中标记为Disable application keypad mode
的框。见这里:the.earth.li/~sgtatham/putty/0.60/htmldoc/…
我必须将vi-beginning-of-line
和vi-end-of-line
绑定添加到viins 模式,以完全解决我的zsh + putty 问题。现在它可以工作了。
@hopla 粘贴的 .zshrc 代码没有成功。所以我不得不使用下面zsh wiki页面http://zshwiki.org/home/zle/bindkeys上的解决方案,在关于从$terminfo []中阅读的部分加上hopla关于将终端类型设置为“linux”的解决方案。 ZSH wiki 页面说基本相同,但没有传递给 bindkey 的“-M ...”选项。不过,这只适用于我的“vi”绑定键模式。
@exhuma 修复对我有用。我在 Windows 上通过 PuTTy -> zsh -> tmux -> emacs 在 CentOS5 机器上驱动 emacs 时遇到问题
自 2001 年以来,PuTTY 的终端类型在 Dickey terminfo 中一直是 putty
。invisible-island.net/ncurses/terminfo.ti.html#tic-putty【参考方案2】:
在 PuTTY 配置对话框中,转到连接 -> 数据,然后在终端类型字符串中键入 linux,然后再连接。
【讨论】:
就是这个! 这对我有用,但另外,如果我想在其中使用鼠标,我必须使用mc -x
启动 Midnight Commander。
Win10 中没有连接 --> PuTTY 0.73 64 位中的数据部分,只有连接 --> SSH,我在任何地方都找不到“终端类型”选项。也许这个答案已经过时了?
@Eric nope, Connection --> 在 Win10 中的 PuTTY 0.74 64 位中,我的数据仍然存在。【参考方案3】:
这对我有用
bindkey -v
bindkey '\eOH' beginning-of-line
bindkey '\eOF' end-of-line
【讨论】:
这搞砸了我的(有点)。现在不是波浪号,而是大写和小写我的字母。 对我来说, bindkey -v 就足够了。 将其放入我的 .zshrc 后:应该在所有发行版中移植的适当答案(尽管不一定是所有版本的 zsh,这里是 ymmv)是使用 zkbd 中的 zkbd 帮助程序实用程序。
键盘定义 键盘、工作站、终端、仿真器和窗口系统的大量可能组合使得 zsh 不可能在每种情况下都有内置的键绑定。在 Functions/Misc 中找到的 zkbd 实用程序可以帮助您快速为您的配置创建键绑定。
将 zkbd 作为自动加载函数或作为 shell 脚本运行:
zsh -f ~/zsh-4.3.17/Functions/Misc/zkbd
当你运行 zkbd 时,它首先要求你输入你的终端类型;如果它提供的默认值是正确的,只需按回车键。然后它会要求您按多个不同的键来确定键盘和终端的特性; zkbd 警告你 如果它发现任何不寻常的东西,例如既不发送 ^H 也不发送 ^? 的 Delete 键。
zkbd 读取的击键被记录为名为 key 的关联数组的定义,写入 HOME 或 ZDOTDIR 目录中的子目录 .zkbd 中的文件。文件名由 TERM、VENDOR 和 OSTYPE 组成 参数,用连字符连接。
您可以使用
source
或.
命令将该文件读入您的.zshrc 或其他启动文件,然后在bindkey 命令中引用key 参数,如下所示:
source $ZDOTDIR:-$HOME/.zkbd/$TERM-$VENDOR-$OSTYPE
[[ -n $key[Left] ]] && bindkey "$key[Left]" backward-char
[[ -n $key[Right] ]] && bindkey "$key[Right]" forward-char
# etc.
请注意,为了使
autoload zkbd
工作,zkbd
文件必须位于 fpath 数组中指定的目录之一中(请参阅 zshparam(1))。如果您有标准的 zsh 安装,则应该已经是这种情况;如果不是,请将 Functions/Misc/zkbd 复制到适当的目录。
参见man -P "less -p 'keyboard definition'" zshcontrib
,或搜索元手册页zshall
【讨论】:
【参考方案5】:距离首次发布此问题已有近 11 年了。当时,一些发行版确实附带了putty
terminfo 条目,但充其量只是平庸。从那以后的几年里,情况有所改善,不再需要十多年来必要的黑客攻击。 PuTTY 仍默认将TERM
设置为xterm
以实现兼容性,但如果您连接到现代的最新系统,您可能会幸运地覆盖它并将其设置为putty-256color
:
-
确保主机有
putty-256color
的terminfo 条目:toe -a | grep -F putty
撤消您可能启用的任何 hack,以使 PuTTY 与 zsh 或其他程序正常工作。
确保 PuTTY 是最新的。它不会在更新可用时通知您,如果它已过时,您可能会遇到很多相同的问题。您可能希望使用 Chocolatey 之类的内容自动保持最新状态。
在 PuTTY 的配置对话框中,转到 Connection -> Data 并将“Terminal-type string”设置为putty-256color
。
当您使用它时,在同一个配置屏幕上,添加一个新环境变量以启用 24 位颜色。这个变量不是标准化的,但它是由许多其他主流终端仿真器(例如,iTerm2)发送的,并且许多程序都理解它。
-
变量:
COLORTERM
值:truecolor
/etc/ssh/sshd_config
并将 COLORTERM
添加到 AcceptEnv
行。
现在一切都应该“正常工作”。如果没有:
-
确保您在进行更改后重新连接,或至少在更改
TERM
后运行exec zsh
。 zsh 在运行时不会对 TERM
中的更改做出反应。
确保 TERM
实际上设置为您想要的:echo $TERM
您使用的是最新版本的发行版吗?例如,如果您正在进行长期支持生命周期构建,即使您的版本在技术上仍受支持,它也可能没有最新的 terminfo 条目。
您使用的是screen
还是tmux
?那是另一整罐蠕虫。在没有先行者的情况下进行测试,以缩小问题发生的范围。在 tmux 中,尝试设置TERM=tmux-256color
。在屏幕内,尝试TERM=screen-256color
。
您使用的是最新版本的 PuTTY 吗?
您是否有 RC 文件正在实现键绑定或其他 hack?尝试使用默认的 RC 文件。
在尝试 terminfo 修复之前,您是否已经更改了各种 PuTTY 设置以尝试修复问题?您可能需要重置这些设置。
【讨论】:
这在 Gentoo 上对我有用——而且 Gentoo 接受了 COLORTERM 而没有做任何更改。 Gentoo 还有一个用于 putty-256color 的 screen terminfo,所以我希望 screen 也能正常工作。 我没有连接 --> PuTTY 0.73 中的数据【参考方案6】:这似乎是一个腻子的东西。 Gnome-terminal 分别为 Home 和 End 发送代码 ^[OH
和 ^[OF
,而 putty 发送 ^[[1~
和 ^[[4~
。 putty 中有一个选项可以将 Home/End 键从 standard 模式更改为 rxvt 模式,这似乎修复了 Home 键,但不是 End 键(现在发送^[Ow
)。猜猜是时候在某处提交错误报告了... :-)
【讨论】:
【参考方案7】:这些绑定似乎不是在 emacs 模式下设置的默认绑定的一部分。
在运行“bindkey -e”后在我的默认 zsh 安装中执行“where-is beginning-of-line”表明它只绑定到 ^a。也许你应该问 zsh 开发人员为什么:-)
【讨论】:
默认的 ubuntu 安装将它们绑定在一个全局 zshrc 文件中,但据我所知,绑定不适用于 putty。【参考方案8】:这对我有用。
将这些行添加到 ~/.zshrc
bindkey "\e[1;5D" backward-word
bindkey "\e[1;5C" forward-word
# ctrl-bs and ctrl-del
bindkey "\e[3;5~" kill-word
bindkey "\C-_" backward-kill-word
# del, home and end
bindkey "\e[3~" delete-char
bindkey "\e[H" beginning-of-line
bindkey "\e[F" end-of-line
# alt-bs
bindkey "\e\d" undo
【讨论】:
以上是关于zsh 中的 Home/End 键不适用于 putty的主要内容,如果未能解决你的问题,请参考以下文章
Angular WithCredentials 不适用于 POST、PUT
mac的Home键、End键、Page UP键和Page DOWN键
URLSession 配置的标头设置仅适用于 PUT,不适用于 POST