not
我有一个显示通知的函数 ( )。因此,我可以用它来显示命令何时完成。
sleep 5; not
然而,有时我忘记添加;not
.在 OS X 的终端(几年前)中,我可以在当前命令运行时输入第二个命令。第二个命令将在第一个命令完成后执行。
因此,我会输入sleep 5
Enter,然后立即输入not
Enter。sleep
终止后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
不过,如果您找到一个不同的菜单完成键,从长远来看,可能会少很多麻烦。对于大多数终端应用程序来说,换行符是一件大事。