【发布时间】:2019-05-21 21:40:48
【问题描述】:
我正在尝试在 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 并按回车键,之后就可以了。我认为这与在 bash 的 bind 中运行的 TIOCSTI 有关。注入yes | less,只是yes 和一个长的git log 会触发这个,但是很多其他的比如echo 和vi 不会。有趣的是,我可以 ctrl-b 注入命令,删除行中的所有内容,自己重新输入,我仍然失去回声。就好像 readline 被一些我无法删除的隐形字符毒害了。
为什么我失去了回声?
我该如何解决?例如。或许需要与 TIOCSTI 一起发送更多代码以确保安全。
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
【问题讨论】:
-
为什么选择这个相当复杂的解决方案而不是仅仅将 C-b 定义为键盘宏? (
bind 'Control-b: "yes | less"') -
@rici 这非常接近。我正在尝试模拟 Ctrl-R ,我可以在其中运行我自己的程序来替换当前行或同时替换它然后执行它,就像我按回车一样。设置
READLINE_LINE适用于前者但不适用于后者。将$( select_from_history )与-x绑定几乎可以工作,只是不会打开ncurses 屏幕。直接插入和运行select_from_history也可以,但是我的终端会变得混乱。