【问题标题】:Why does TIOCSTI injection disable stty echo in bash when used with bind?为什么 TIOCSTI 注入在与 bind 一起使用时会禁用 bash 中的 stty echo?
【发布时间】: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 会触发这个,但是很多其他的比如echovi 不会。有趣的是,我可以 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 也可以,但是我的终端会变得混乱。

标签: bash terminal


【解决方案1】:

我相信这是a bug in bash,它不是由专门的TIOCSTI 注入触发,而是通过在bind -x 处理程序中运行程序(在本例中为perl)。

您的示例仍会导致 GNU bash, version 5.1.8(1)-release (x86_64-pc-linux-gnu) 中描述的错误行为,但在从包含修复的 devel 分支 (GNU bash, version 5.2.0(1)-alpha (x86_64-pc-linux-gnu)) 构建的版本中,一切正常。

【讨论】:

    【解决方案2】:

    如果您只需要某种键盘宏,您可以在 ~/.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)在我看来是更安全的方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      • 2011-09-27
      • 2014-05-15
      • 2013-04-04
      • 1970-01-01
      • 1970-01-01
      • 2013-11-15
      相关资源
      最近更新 更多