我是 KSH 的新手,必须在工作中使用它。版本是:
sh (AT&T 研究) 93u+ 2012-08-01
在 RHEL 上。我以前使用过 tcsh 并使用它的 bindkey 工具为我提供了一些很好的命令行操作快捷方式。我在 KSH 中找到了“keybind”函数的代码,并用它来使 home、end 和 delete 按我想要的方式工作:
keybind $'\eOH' $'\001'
keybind $'\eOF' $'\005'
keybind $'\e[F' $'\005'
keybind $'\e[3~' $'\004'
我实际上不确定为什么我有两个对应于“End”的内容,但我确实如此。无论如何,棘手的部分是我想要 ctrl+左/右箭头跳过一个单词,而不是使用 Mf 或 Mb。当我尝试获取 ctrl-left arrow 的代码时,它显示:
^[[1;5D
但我似乎无法让它在 keybind 命令中工作。由于分号的存在,它看起来几乎像是一个复合按键。我之前也没有看到过这个问题,因此我们将不胜感激。
谢谢,马特
答案1
ksh 手册页中记录的 KEYBD 陷阱被调用以处理以转义开头的传入字符序列。这个序列的结尾没有描述,但似乎;
会结束它。
假设您的按键绑定功能如下所示文章,那么您的绑定就会失败,因为首先调用陷阱代码 for \e[1;
,然后调用 for5
和D
。
一种解决方案是更改陷阱代码以记住初始序列,并在以后使用它,如下所示:
# original code from http://www.bolthole.com/solaris/ksh-oddthings.html
typeset -A Keytable
# trap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD
function keybind # key action
{
typeset key=$(print -f "%q" "$2")
case $# in
2) Keytable[$1]=' .sh.edchar=${.sh.edmode}'"$key" ;;
1) unset Keytable[$1] ;;
*) print -u2 "Usage: $0 key [action]" ;;
esac
}
# new function to handle ";" causing end of sequence
# https://unix.stackexchange.com/a/425980/119298
function myfn {
typeset -S state
case "$state${.sh.edchar}" in
$'\e[1;') state=${.sh.edchar}
.sh.edchar=
return ;;
$'\e[1;5') state="$state${.sh.edchar}"
.sh.edchar=
return ;;
$'\e[1;5'?) state=
.sh.edchar=$'\e[1;5'"${.sh.edchar}" ;;
esac
eval "${Keytable[${.sh.edchar}]}"
}
trap myfn KEYBD
keybind $'\e[1;5D' $'\eb'
keybind $'\e[1;5C' $'\ef'