我正在尝试绑定bash中的密钥以使用TIOCSTI(example here)将命令注入终端。直到我注入某些命令,此方法才能正常工作。最终目标是替换bash反向搜索(ctrl-r),但这是显示我的问题的示例。
# Test using a clean environment
env -i bash --noprofile --norc
# Define TIOCSTI helper
function inject() { perl -e 'ioctl(STDIN, 0x5412, $_) for split "", join " ", @ARGV' "$@"; }
# Bind ctrl-b to inject 'yes | less' as a test
bind -x '"\C-b":"inject yes \| less"'
<press ctrl-b>yes | less<press enter>
WARNING: terminal is not fully functional
y (press RETURN)
y
...
<press q to exit less>
# Terminal is now foobared. In particular I can't see what I type. Why?
# Enable echo
stty echo
如果我只是输入inject yes \| less
并按Enter,那么终端就可以了。我认为TIOCSTI与在bash的bind
中运行有关。注入yes | less
,仅注入yes
和长的git log
会触发此事件,但是诸如echo
和vi
之类的许多其他事件则不会触发。有趣的是,我可以按ctrl-b注入命令,删除行中的所有内容,然后自己重新输入,但仍然会丢失回显。就像readline被一些我无法删除的不可见字符所毒害。
我为什么会丢失回声?
我该如何解决?例如。也许还需要通过TIOCSTI发送更多代码以确保安全。
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
答案 0 :(得分:0)
如果只需要某种键盘宏,则可以在〜/ .inputrc中放置这样的示例(例如):
# F12 has a keyboard macro:
"\e[24~": "cls; (date; make 2>&1 || flash 1 >/dev/console 2>&1; date) | tee make.res^M"
注1:^ M是实际的Control-M字符(即\ r,CR,回车符)。
注2:我认为'.inputrc'对间距有些挑剔;我似乎想知道,密钥和宏定义之间必须恰好有一个空格。
注意3:例如,要查看F12的输出,请运行cat
并按F12键并记下它打印的字符串。
在风风火火的年代,我曾经有多年了,我自己编译了所有该死的软件包,并只保留了所有make
日志(cls基本上是tput clear
的脚本, flash是一种自家编写的脚本,用于闪烁终端并响铃:)
尾注:像上面这样的宏最后包含一个CR,这让我感到紧张,我(现在)认为很危险。只是将命令放在提示符后,等待您的交互式CR(或^ C)的宏对我来说是更安全的方法。