23

In bash, the home/end/delete key is inserting a tilde, or if preceded by escape key: [1~

So I type echo hellp, move cursor to hel|lp and type delete, and bam, i got ~tilde

Also, I type echo hellp, move cursor to hel|lp and type esc then delete, and bam, I got [3~

$ echo hel~lp
hel~lp

$ echo hell[3~o
hell[3~o
~

My version of bash:

$ bash --version
GNU bash, version 3.1.17(1)-release (i686-pc-msys)
Copyright (C) 2005 Free Software Foundation, Inc.

What I want is behavior like cmd.exe:

  1. I want Esc to clear the current line / buffer
  2. I want Home to move cursor to start of line before first character
  3. I want End to move cursor to end of line before first character
  4. I want delete to delete the next character (right of cursor) from current line/buffer

What do I have to edit to fix this? Is this default on your bash?

update: i'm on a windows machine running a windows program, sh.exe ( as you can see above GNU bash), compiled with mingw for msys:

$ uname -s -m -o
MINGW32_NT-5.1 i686 Msys
  • windows, no terminal emulator, msys.bat, if I knew how to report the setting, I wouldn't be asking how to set them – optional Feb 16 '13 at 3:39
24

You customize bash via an .inputrc file in your /home/username , you can copy the default

cp /etc/inputrc.default   ~/.inputrc

here is mine (comments start with # )

# Key-bindings for the command-line editor.

# Ask before displaying >50 items
# Since $WINDIR $PATH var can be in $PATH, this could list
# all window exectables in C:\WINDOWS
set completion-query-items 50

# Ignore case for the command-line-completion functionality
# on:  default to a Windows style console
# off: default to a *nix style console
set completion-ignore-case on

# none, visible or audible
set bell-style audible

# disable/enable 8bit input
set meta-flag on
set input-meta on
set output-meta off
set convert-meta on

# visible-stats
# Append a mark according to the file type in a listing
set visible-stats off
set mark-directories on

# Show all instead of beeping first
set show-all-if-ambiguous off

# MSYSTEM is emacs based
$if mode=emacs
    # Common to Console & RXVT
    "\C-?": backward-kill-line          # Ctrl-BackSpace
    "\e[2~": paste-from-clipboard       # "Ins. Key"
    "\e[5~": beginning-of-history       # Page up
    "\e[6~": end-of-history             # Page down

    $if term=msys # RXVT
        "\e[7~": beginning-of-line      # Home Key
        "\e[8~": end-of-line            # End Key
        "\e[11~": display-shell-version # F1
        "\e[15~": re-read-init-file     # F5
    #$endif
    #$if term=cygwin # Console
    $else
        "\e[1~": beginning-of-line      # Home Key
        "\e[4~": end-of-line            # End Key


"\e[3~": delete-char            # Delete Key
#~      "\e\e[D": backward-word         # Alt-LeftArrow
#~      "\e\e[C": forward-word          # Alt-RightArrow
            "\M-\e[D": backward-word            # Alt-LeftArrow
            "\M-\e[C": forward-word         # Alt-RightArrow
    `#~`        "\C-\E[D": backward-word        # Ctrl-LeftArrow, nowork, can't be made to work
    #~`enter preformatted text here`        "\C-\E[C": forward-word         # Ctrl-RightArrow, nowork, can't be made to work
    #~ to see current bindings use    bind -q backward-kill-line
            "\e\e": kill-whole-line        # double/triple escape works :) Esc/Escape to delete current line like cmd.exe

        $endif
    $endif

to find out what you need to type in your inputrc on the left side (the escape code, as it can vary between laptop/desktop...), at the prompt type echo ' then type Ctrl-V followed by the key , like Home, then type ' example

$ echo ' home key ^[[1~  '
 home key
~
$ echo ' end key ^[[4~  '
 end key
~
$ echo ' pg up page up ^[[5~ '
 pg up page up
~
$ echo ' pg dn page down ^[[6~ '
 pg dn page down
~

then replace each ^[ with \e add \M- for Alt theoretically you'd use \C- for Ctrl but it currently doesn't work (windows limitation)

the available commands (like backward-kill-line) are listed in http://www.gnu.org/software/bash/manual/bashref.html#index-backward_002dkill_002dline-_0028C_002dx-Rubout_0029

you can view existing keyboard shortcuts/bindings with bind -p or

$ bind -q backward-kill-word
backward-kill-word can be invoked via "\M-\C-h", "\M-\C-?".
~
$ bind -q backward-word
backward-word can be invoked via "\M-\M-[D", "\M-b", "\C-\E[[D".
~
$ bind -q beginning-of-line
beginning-of-line can be invoked via "\C-a", "\M-OH", "\M-[1~", "\M-[H".
~

don't mess with TERMCAP

| improve this answer | |
  • find / -name 'inputrc.default' finds nothing on my machine. My home and end used to work... :( Also, FYI to others: To reload the .inputrc file, use bind -f ~/.inputrc. – aliteralmind Jan 10 '15 at 20:47
  • Ah! Correction: I used your .inputrc, except for the $if mode=emacs block. I added these two lines, and they work again!! :D "\e[1~": beginning-of-line ... "\e[4~": end-of-line. – aliteralmind Jan 10 '15 at 20:57
  • on RHL - the default file in /etc/inputrc – Deian Feb 16 '16 at 20:46
  • unfortunately I don't have write access to that file on a cluster machine. – Herman Toothrot Sep 10 '16 at 22:37
5

Well, since you say you're working on Windows and not using a proper terminal emulator such as PuTTY (with mintty, puttycyg et al), I would recommend you consult the readline documentation and learn the shortcuts for readline. It'll be better in the long run.

If you were to use a terminal emulator instead of the console window (not talking about the interpreter/shell here) that comes with Windows, you'd get a more configurable alternative. Once you attempt using other programs like Vim, things will only get worse.

The gist: use a proper terminal emulator, even on Windows or learn the readline shortcuts. I tested the ones I use most just now and they work with msys.bat.

mingw-get install mintty && mintty

The file to edit would be /usr/share/terminfo (which doesn't exist in MinGW) - use tic to "compile" rules (which isn't even included because everyone knows that the support would be severely crippled). However, I haven't seen any useful development to make this even near usable on Windows. This is why you should use a proper terminal emulator in the first place. But I'm sure a surgeon will be able to use a kitchen knife for surgery, so why shouldn't you use the Windows built-in console windows. Good luck.

| improve this answer | |
4

Check for installation of Readline

When this happens on a minimal installation of recent Debian/Ubuntu, it's probably because you haven't installed the readline-common package. Simply installing the package will solve it.

E.g. on Docker with Debian Stretch typing ls HOME:

$ docker run --rm -it debian:stretch
root@6ae7baea9e5a:/# ls~

$ docker run -it --name=debian-stretch-readline-temp debian:stretch
root@2092cb968232:/# apt-get update
root@2092cb968232:/# apt-get install readline-common

$ docker commit debian-stretch-readline-temp debian-stretch-with-readline
$ docker run --rm -it debian-stretch-with-readline
root@53739343e9f7:/# ls

Please note that after installing readline-common it will only have effect on new login shells.

| improve this answer | |
  • exec bash is a way of replacing the current bash instance with a new one, without exiting the terminal (as may be needed when playing in a container pTTY). – Kevin Aug 18 '17 at 13:20
  • @Kevin While that's a valid statement, what does it have to do with the context of the Q&A here? – gertvdijk Aug 18 '17 at 15:18
  • 1
    that is why I left it as comment instead of suggesting it as an edit to your answer. You noted the need of a new shell in order to use the freshly installed readline-common, and showed committing a container as an image as one means of achieving that. Especially, since you used Docker as your example, I thought my comment was relevant. – Kevin Aug 19 '17 at 19:45
  • @Kevin Ah, okay, well misunderstood your point then. Many ways exist on getting a new login shell, yours is one of them. :) – gertvdijk Aug 20 '17 at 21:52
2

I found the following helpful as well: https://wiki.archlinux.org/index.php/Home_and_End_keys_not_working

Specifically:

If your keys are not working, it could be because your particular terminal sends escape codes not in this list. First you need to find out what escape codes are being sent. To see them, you can use a Readline command called "quoted-insert" or run the command showkey --scancodes which outputs the value of a key verbatim. The default binding for quoted-insert is Ctrl+V.

For example, you could give the following series of inputs in your terminal:

Ctrl+V
Home
Spacebar
Ctrl+V
End

And get as output

$ ^[[1~ ^[[4~

The ^[ indicates an escape character in your shell, so this means that your Home key has an escape code of [1~ and you End key has an escape code of [4~. Since these escape codes are not listed in the default Readline config, you will need to add them:

"\e[1~": beginning-of-line
"\e[4~": end-of-line

Note that Readline uses \e to indicate an escape character.

The relevant piece for me was putting this in inputrc:

"\e[1~": beginning-of-line
"\e[4~": end-of-line
| improve this answer | |

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.