Velvet Star Monitor

Standout celebrity highlights with iconic style.

general

Bash do not execute command on Ctrl+D

Writer Matthew Martinez

Typing Ctrl+D exits bash shell as expected, but only when the command line is empty. When there's something typed on the command line, it gets executed instead as if Enter was pressed. Is there a way to make it always exit?

5

1 Answer

Normally the output of stty -a contains eof = ^D. This means the terminal sends EOF when you press Ctrl+d. Bash uses Readline and when there are no characters on the line and point is at the beginning of the line, Readline interprets it as the end of input, returns EOF and Bash exits.

In your case this functionality seems intact.

When the conditions are not met, a regular binding (if any) applies. Check the binding with

bind -p | grep -F '"\C-d'

With the default bindings the output is "\C-d": delete-char. And this:

bind -q accept-line

usually generates

accept-line can be invoked via "\C-j", "\C-m".

When I press Ctrl+v, Enter, I get ^M which means Enter is equivalent to Ctrl+m which accepts the line. This is the mechanism. I expect you to learn that in your case Ctrl+d triggers accept-line as well. This would explain the behavior in question.

Another possibility is your terminal emulator sends ^J when you press Ctrl+d and stty is set to send EOF upon ^J. This would be very unusual but it could also replicate the behavior.


Is there a way to make it always exit?

Yes. Now I assume your terminal emulator sends ^D when you press Ctrl+d and the unusual behavior you reported (executing the line) is only because of unusual binding in Readline.

In my Bash the default binding for Ctrl+u is unix-line-discard, this clears the line. I can make Ctrl+d send Ctrl+u and Ctrl+d. This will effectively work as Ctrl+d when the line is empty.

In Bash:

bind '"\C-d": "\C-u\C-d"'

Or (permanent solution) in your ~/.inputrc (or /etc/inputrc):

"\C-d": "\C-u\C-d"

In case you want to change your unusual binding to the default one, invoke

bind '"\C-d": delete-char'

but this will affect just the shell you run it in. A permanent fix is to find where the undesired binding is defined and delete the binding. It may be

  • in ~/.inputrc or /etc/inputrc (a line like "\C-d": accept-line),
  • or in ~/.bashrc or /etc/bash.bashrc or another file that gets sourced (a line like bind '"\C-d": accept-line').
1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy