在不同的 shell 中进行测试

在不同的 shell 中进行测试

not我有一个显示通知的函数 ( )。因此,我可以用它来显示命令何时完成。

sleep 5; not

然而,有时我忘记添加;not.在 OS X 的终端(几年前)中,我可以在当前命令运行时输入第二个命令。第二个命令将在第一个命令完成后执行。

因此,我会输入sleep 5Enter,然后立即输入notEntersleep终止后not就会执行。

然而,我在 Linux 中的经验是不会发生这种情况。终止后sleep,命令行显示not,但从Enter不注册。我测试过 Terminator、Konsole 和 tty。

此行为是否依赖于终端仿真器,如果是,是否有任何可以按我想要的方式工作?或者,有没有办法让这个功能在我选择的终端(终结者)中工作?

在不同的 shell 中进行测试

不起作用,即第二个命令未注册:

  • bash
  • bash --norc
  • bash --norc --noprofile
  • sh

确实有效,即第二个命令寄存器:

  • bash --norc --noprofile --noediting
  • zsh

~/.inputrc我选择性地从默认shell中删除了行并bash再次进行了测试。我将问题追溯到以下行。删除后,第二个命令将按预期注册。

Control-j: menu-complete

奇怪的是,如果我尝试绑定(比如说)Ctrl+ i,就没有问题。为什么此条目会阻止第二个命令注册,并且有没有办法在具有我想要的第二个命令的行为的同时仍然使用Ctrl+ jfor ?menu-complete

答案1

假设您正在使用 bash:尝试按 ^Z(即 Ctrl-Z)来停止该进程,将其移动到后台,并获得另一个 bash 提示符。输入 fg; not,前者继续停止的进程并在完成时返回。

或者,找出您要等待的程序的进程 ID,假设它是 2342。在新的 Should 中,键入

until kill -0 2342; do sleep 1; done; not

这将每秒检查一次。

答案2

好吧,根据您的一些编辑,您已经CTRL+J绑定到bindkey宏命令。这解释了您bash考虑readline默认行为的问题。

通常readline以非常类似的stty raw模式读取输入。输入字符在键入后立即被读入,并且 shell 的行编辑器会处理自己的缓冲。readline当它获取前台时将终端设置为原始状态,并在调用另一个前台进程组时将其恢复到之前的状态。

CTRL+J是 ASCII 换行符。ABCDEFGHIJ距 NUL 10 个字节。因为您已配置readline为吃掉此字符,然后展开它在菜单完成中执行的任何命令行的剩余部分,所以提前输入将不起作用。当预先输入由内核的行规则缓冲时,终端处于与readline在前台时不同的状态。

readline位于前台时,它会对输入回车符 -> 换行符进行自己的转换,并且终端驱动程序根本不转换它。但是,当您输入预先输入的内容时,终端驱动程序通常会将回车符转换为换行符,可以使用stty [-]icrnl.因此,您的返回键足以用于实时输入的命令,但终端的行规则发送的换行符将被解释为菜单完整命令。

您可以使用 告诉终端驱动程序停止此转换stty -icrnl。这可能至少需要一点时间来适应。其他接受终端输入的命令通常会期望换行符而不是返回值,因此您要么必须CTRL+J在它们控制前台时显式使用它们,要么教它们像bash这样做一样处理返回值。

您已经提到,read从终端读取内容时,它无法按预期工作。同样,如果您明确地用于CTRL+J结束输入行,则可能会出现这种情况。或者...你可以教它:

read()
    if    [ -t 0 ]
    then  command read -d $'\r' "$@"
    else  command read "$@"
    fi

不过,如果您找到一个不同的菜单完成键,从长远来看,可能会少很多麻烦。对于大多数终端应用程序来说,换行符是一件大事。

相关内容