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-linebindkey '^[OF' end-of-line 【参考方案1】:

我发现这是一个组合:

一个

ZSH 开发者认为 ZSH 不应该定义 HomeEndDel、...键的动作。

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 作为终端类型发送到远程主机。但是在某处搞砸了,并且没有为 HomeEnd 发送正确的控制代码,......这是人们对xterm 的期望。或者xterm 终端不应该发送这些或任何东西......(Del 键在xterm 中确实有效,但是,如果你在 ZSH 中配置它)。另请注意,您的小键盘键在 Vim 中的行为很有趣,例如使用 xterm 终端。

解决方法是配置Putty发送另一种终端类型。我试过xterm-colorlinuxxterm-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-linevi-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 后: 不再起作用,只打印出 ^P^N - 但是使用 '\e[1~' 和 '\e [4~'作品【参考方案4】:

应该在所有发行版中移植的适当答案(尽管不一定是所有版本的 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
    在撰写本文时,我还没有找到默认情况下通过 SSH 接受 COLORTERM 变量的发行版。您需要在主机上编辑 OpenSSH 配置以允许它。例如,在类似 Debian 的发行版上,编辑 /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

file_put_contents 不适用于 json laravel 和 php

Spring JPA 更新不适用于嵌套对象

多个 CORS 适用于 GET 但不适用于 PUT/POST 与飞行前请求 Web api 2