Bash 不执行 Ctrl+D 上的命令

lev*_*ied 2 linux bash

键入Ctrl+D会按预期退出 bash shell,但仅当命令行为空时才有效。当在命令行上输入某些内容时,它会被执行,就像Enter被按下一样。有没有办法让它永远退出?

Kam*_*ski 6

通常 的输出stty -a包含eof = ^D. Ctrl这意味着当您按+时终端会发送 EOF d。Bash 使用 Readline,当行中没有字符并且点位于行的开头时,Readline 将其解释为输入结束,返回 EOF 并且 Bash 退出。

就您而言,此功能似乎完好无损。

当不满足条件时,将适用常规绑定(如果有)。检查绑定

bind -p | grep -F '"\C-d'
Run Code Online (Sandbox Code Playgroud)

使用默认绑定时,输出为"\C-d": delete-char. 和这个:

bind -q accept-line
Run Code Online (Sandbox Code Playgroud)

通常会产生

accept-line can be invoked via "\C-j", "\C-m".
Run Code Online (Sandbox Code Playgroud)

当我按Ctrl+ v,时Enter,我得到^M的意思Enter相当于接受该行的Ctrl+ 。m这就是机制。我希望您也能在您的案例中了解这一点Ctrl+d触发器。accept-line这可以解释相关行为。

^J另一种可能性是您的终端仿真器在您按Ctrl+时发送d,并stty设置为在 时发送 EOF ^J。这将是非常不寻常的,但它也可以复制这种行为。


有没有办法让它永远退出?

是的。现在我假设您的终端模拟器^D在您按Ctrl+时发送d,并且您报告的异常行为(执行该行)只是因为 Readline 中的异常绑定。

Ctrl在我的 Bash 中, +的默认绑定uunix-line-discard,这会清除该行。我可以制作Ctrl+d发送Ctrl+u Ctrl+ d。当该行为空时,这将有效地用作Ctrl+ 。d

在重击中:

bind '"\C-d": "\C-u\C-d"'
Run Code Online (Sandbox Code Playgroud)

或者(永久解决方案)在您的~/.inputrc(或/etc/inputrc)中:

"\C-d": "\C-u\C-d"
Run Code Online (Sandbox Code Playgroud)

如果您想将不寻常的绑定更改为默认绑定,请调用

bind '"\C-d": delete-char'
Run Code Online (Sandbox Code Playgroud)

但这只会影响您运行它的 shell。永久修复是找到定义不需要的绑定的位置并删除该绑定。可能是

  • ~/.inputrcor /etc/inputrc (类似 的行"\C-d": accept-line)中,
  • 或在~/.bashrc/etc/bash.bashrc或另一个获取来源的文件中(类似 的行bind '"\C-d": accept-line')。