如何read
按 退出内置功能Esc?
示例代码片段没有反应Esc:
#!/bin/bash
echo "Quit - press key Esc"
echo "Enter name :"
read
答案1
在 Bash 中使用 readline。当+是唯一的输入时read -e
,它将以退出状态退出。因此,如果我们设法触发然后发送,它应该可以解决问题。1
CtrlDEsckill-whole-line
\C-d
我无法让单个按键按顺序执行这两件事。但是,我可以绑定kill-whole-line
到另一个按键并发送Esc按键并\C-d
:
set -o emacs
bind '"\C-w": kill-whole-line'
bind '"\e": "\C-w\C-d"'
read -e
如果您想在之后read
返回退出状态,第二个绑定应该是:0
Esc
bind '"\e": "\C-w\C-j"'
或者您可以选择传递一些特定的字符串作为输入:
bind '"\e": "\C-w---interrupted---\C-j"'
或者Esc简单地表现得像Enter(接受输入):
bind '"\e": "\C-j"' # no prior \C-w binding required for this
注意多次快速Esc击打不仅仅是几次逃脱。有些人倾向于快速按Esc几次以快速中止。出于这个原因,您可能希望绑定"\e\e"
到与相同的字符串"\e"
。
如果退出后“剩下”的此类笔划很少read -e
,它们将在稍后被“利用”。您可能不希望出现这种情况,因此请使用以下命令从 stdin 中丢弃多余的字符:
read -st 0.1 -n 1000000
如果您在第一个之后立即运行它read
,请考虑更长的超时时间来捕获所有的击键Esc,再加上一条先前的消息,以使不耐烦的用户停止击键。
整个脚本可能如下所示:
#!/bin/bash
set -o emacs
bind '"\C-w": kill-whole-line'
bind '"\e": "\C-w\C-d"'
bind '"\e\e": "\C-w\C-d"'
IFS= read -rep "Enter name (ESC to exit): " || {
printf '\nAborting\n'
read -st 1 -n 1000000
exit 1
}
printf 'The input was %s\n' "$REPLY"
脚本(除非有源)在其自己的 shell 中运行,因此这些绑定不会影响您从中调用它的 shell。无需解除绑定,除非脚本本身继续运行,并且绑定在某些时候干扰了某些东西。