Delete key doesn't work on command line
Solution 1
For Googlers:
Whew. For something that should be so simple, this was hard.
The short solution is use the following to set the delete key (in kshrc
or wherever),
bind '^[[3'=prefix-2
bind '^[[3~'=delete-char-forward
And set your PuTTy terminal settings to rxvt
instead of Standard
.
This thing that really helped me get this working was: http://www.mail-archive.com/[email protected]/msg81796.html
ksh does silly things with the home and end keys. Basically, I couldn't make it tell the difference between Home, End, and Delete at the same time. Whatever was last bound, all three keys would do. Changing what PuTTy sent for these keys helped immensely.
Note: Some folks suggest if you want to see what code the shell is getting when you press a key, type cat
, press enter, then push the key. For my shell, this didn't work. I got ~
for all the control keys. What I did instead was press Esc
once, then press the key. The control code would show then show up. Use that control code in bind
and you're all set.
Solution 2
If shell is running inside a gnome terminal window, then menu into: Edit
| Preferences
| Profiles
and select a profile, then select the Compatibility
tab, and change the Delete key generates
to Automatic
. (Or if this fails try the other choices there.)
Also, you can enter ^v Del
and ^v Backspace
, (i.e. Control-v followed by the delete key, and Control-v followed by the backspace key), to find the returned 'terminal' sequence codes.
And for inspection use the showkey
command as showkey -s
, showkey -k
, and/or showkey -a
(i.e. the three layers) and then press the Del
and Backspace
keys for:
I) raw output from a keyboard
II) output from tty driver
III) character strings given to a (ansi) terminal
From this I noticed that when using stty (e.g. stty1) that my shell behavior was different from when using xterm (from within a Graphical X terminal). Del deleted correctly forwards (right) in stty1, but backwards (left) in my xterm.
Solution 3
The existing two answers did not work for me going from Linux (Ubuntu 18.10) bash, via SSH to Solaris 11.3 bash, using gnome terminal.
I found I needed to use the bind
command, but with a work-around, as I could not get a native Delete to function.
So the work-around is that when Delete is pressed, to simulate a delete by mapping the delete keypress to → and Backspace.
bind '"^[[3~":"^[[C^?"'
To type that, use the key-presses:
CTRL-vDelete for the first part
and CTRL-v→CTRL-vBackspace for the second.
(or use \e
for the escape instead, e.g.: "\e[3~"
)
It's not perfect, if you Delete at end-of-line, it still backspaces. But it saves me having to backspace-out the ~
character umpteen times a day.
Solution 4
According to man ksh
on my Debian 10 system, prefix-1
"introduces a 2-character command sequence" and prefix-2
"introduces a multi-character command sequence". Essentially, they tell the shell "don't process this yet, there's supposed to be a longer sequence of characters - wait for the complete sequence."
Modern Unix/Linux terminal sessions generally run on terminal emulators: they essentially emulate (an extended version of) some type of computer terminal connected over a serial port. With many terminals, the mapping between keyboard keys and characters sent to the computer was not strictly one-to-one: because there were no standardized ASCII control characters for all the various non-character keys of the keyboard, some keys will send multi-character sequences. The function keys, arrow keys, Home, End, Insert, Delete, PgUp and PgDn belong to this group.
The Esc key is represented as ^[
, in other words Control+[. And when you look at an ASCII code table, you'll see that the Control key essentially subtracts 64 (i.e. flips one bit) from the value of the regular character combined with it. So ^[
is just a single ASCII control character that has the special name "ESC".
Your bind | grep prefix
output indicates ^[
is already recognized as prefix-1
, and ^[[
as prefix-2
.
The Delete key actually sends a sequence that would be the equivalent of Esc [ 3 ~.
So the shell must parse it one character/byte at a time, like this:
- received Esc: also known as
^[
, matchesprefix-1
, so wait for at least one more character and combine this with it - received [: combined with the previous prefix character it's
^[[
which matchesprefix-2
, so wait for more still and keep combining the characters. - received 3: combined with the previous prefixes it's
^[[3
which isprefix-2
again, so keep waiting and combining. - received ~: now the resulting combination is
^[[3~
which now matches the binding fordelete-char-forward
.
Related videos on Youtube
user3330406
Updated on September 18, 2022Comments
-
user3330406 almost 2 years
**Note: I asked this same question on SuperUser, but didn't get any response. I now realize this is a more appropriate forum for this particular question.*
In a ksh shell, the Delete key doesn't work appropriately on the command line. I get a ~ when I press Delete.
How do I:
- bind the functionality of "Delete the character at the cursor" to the Delete keyboard button? (Control-D behaves like I expect the delete button to work and my attempts at using an alias were unsuccessful and likely naive.)
- bind the functionality of "Move to the first of the line" to the Home keyboard button? (Control A does this now, but I want Home to do it.)
- bind the functionality of "Move to the end of the line" to the End keyboard button? (Control E does this now, but I want end to do it.)
Final(?) Update
I stumbled across something that works, but I don't understand quite why. This works:
bind '^[[3'=prefix-2 bind '^[[3~'=delete-char-forward
According to http://www.qnx.com/developers/docs/6.3.2/neutrino/utilities/k/ksh.html#bind,
prefix-2 Key binding: ^X, ^[[ Introduces a 2-character command sequence.
So my updated question is why do I need to use
prefix-2
for this? Please translate for me so I can understand so I don't have to bug everyone again about this.OLD STUFF FOLLOWS
UPDATE
It turns out that ESC in QNX is
^[
. Using the commandbind '^[[3~'='delete-char-backward'
I am able to get the cursor to overwrite the character under the cursor with a~
. This is some progress at least--I now know how to spell Delete Key for the shell. Most things I have seen on the web say that the delete key is^?
, but that doesn't seem to work for me. Also, I should mention I am accessing this via PuTTy.I don't understand because Control D does what I want the delete key to do. I tried binding it to
eot-or-delete
again to no avail.This should be simple, right?
UPDATE 2:
bind | grep prefix ^X = prefix-2 ^[ = prefix-1 ÿ = prefix-3 ^[O = prefix-2 ^[[ = prefix-2 bind | grep '[^ -~]' ÿ = prefix-3 à = beginning-of-line à¡ = up-history ठ= backward-char ঠ= forward-char ਠ= end-of-line à© = down-history ଠ= delete-char-forward à´ = backward-word ච= forward-word
UPDATE 3: More of my settings
ENV setting
echo $ENV /etc/kshrc
BIND Complete Output
bind ^A = beginning-of-line ^B = backward-char ^C = abort ^D = eot-or-delete ^E = end-of-line ^F = forward-char ^G = abort ^H = delete-char-backward ^I = complete ^J = newline ^K = kill-to-eol ^L = redraw ^M = newline ^N = down-history ^O = newline-and-next ^P = up-history ^R = search-history ^T = transpose-chars ^U = kill-line ^V = version ^W = kill-region ^X = prefix-2 ^Y = yank ^[ = prefix-1 ^\ = no-op ^] = search-character-forward ^^ = quote ^_ = eot ^? = delete-char-backward ÿ = prefix-3 ^[^H = delete-word-backward ^[^X = complete-file ^[^[ = complete ^[^] = search-character-backward ^[ = set-mark-command ^[# = comment ^[* = expand-file ^[. = prev-hist-word ^[0 = set-arg ^[1 = set-arg ^[2 = set-arg ^[3 = set-arg ^[4 = set-arg ^[5 = set-arg ^[6 = set-arg ^[7 = set-arg ^[8 = set-arg ^[9 = set-arg ^[< = beginning-of-history ^[= = complete-list ^[> = end-of-history ^[? = list ^[C = capitalize-word ^[L = downcase-word ^[O = prefix-2 ^[U = upcase-word ^[[ = prefix-2 ^[_ = prev-hist-word ^[b = backward-word ^[c = capitalize-word ^[d = delete-word-forward ^[f = forward-word ^[g = goto-history ^[h = delete-word-backward ^[l = downcase-word ^[u = upcase-word ^[y = yank-pop ^[^? = delete-word-backward ^X^X = exchange-point-and-mark ^X^Y = list-file ^X^[ = complete-command ^X? = list-command ^XA = up-history ^XB = down-history ^XC = forward-char ^XD = backward-char ^XH = beginning-of-line ^XP = delete-char-forward ^XY = end-of-line ^Xc = forward-word ^Xd = backward-word ^Xw = end-of-line à = beginning-of-line à¡ = up-history ठ= backward-char ঠ= forward-char ਠ= end-of-line à© = down-history ଠ= delete-char-forward à´ = backward-word ච= forward-word
/etc/kshrc
/etc # cat kshrc case $- in *i*) export SHELL_COLOR_BLUE="print -n \\033[0;34m" export SHELL_COLOR_GREEN="print -n \\033[0;32m" export SHELL_COLOR_RED="print -n \\033[0;31m" export SHELL_COLOR_LIGHTGRAY="print -n \\033[0;37m" export SHELL_COLOR_YELLOW="print -n \\033[1;33m" export COLOR_BLACK="\\033[0;30m" export COLOR_BLUE="\\033[0;34m" export COLOR_GREEN="\\033[0;32m" export COLOR_CYAN="\\033[0;36m" export COLOR_RED="\\033[0;31m" export COLOR_PURPLE="\\033[0;35m" export COLOR_BROWN="\\033[0;33m" export COLOR_LIGHTGRAY="\\033[0;37m" export COLOR_DARKGRAY="\\033[1;30m" export COLOR_LIGHTBLUE="\\033[1;34m" export COLOR_LIGHTGREEN="\\033[1;32m" export COLOR_LIGHTCYAN="\\033[1;36m" export COLOR_LIGHTRED="\\033[1;31m" export COLOR_LIGHTPURPLE="\\033[1;35m" export COLOR_YELLOW="\\033[1;33m" export COLOR_WHITE="\\033[1;37m" if [[ `id -u` -eq 0 ]]; then export PS1=`$SHELL_COLOR_RED`'$(hostname -s):'`$SHELL_COLOR_YELLOW`'$(pwd) # '`$SHELL_COLOR_LIGHTGRAY` else export PS1=`$SHELL_COLOR_BLUE`'$(hostname -s):'`$SHELL_COLOR_GREEN`'$(pwd) $ '`$SHELL_COLOR_LIGHTGRAY` fi esac
PuTTy settings:
Notes that may or may not matter, but could provide background:
The shell is "PD KSH v5.2.14 99/07/13.2". Yes, I have no option to upgrade... it's an embedded system. "Get a modern shell" is not a viable answer. The operating system is QNX Neutrino 6.4.1.
bind shows the following:
bind | grep del ^D = eot-or-delete ^H = delete-char-backward ^? = delete-char-backward ^[^H = delete-word-backward ^[d = delete-word-forward ^[h = delete-word-backward ^[^? = delete-word-backward ^XP = delete-char-forward ଠ= delete-char-forward
infocmp shows the following:
infocmp # Reconstructed via infocmp from file: /usr/lib/terminfo/x/xterm xterm|vs100|xterm terminal emulator, am, km, mir, msgr, xenl, xon, cols#80, it#8, lines#65, vt@, acsc=Oa``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, bel=^G, blink=@, bold=\E[1m, clear=\E[H\E[2J, cr=^M, csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H, cud=\E[%p1%dB, cud1=\E[B, cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A, dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, dl1=\E[M, ed=\E[J, el=\E[K, el1=\E[1K$<3>, enacs=\E(B\E)0, home=\E[H, ht=^I, hts=\EH, ich=\E[%p1%d@, ich1=\E[2~, il=\E[%p1%dL, il1=\E[L, ind=^J, is1=\E=\E[?1l, kBEG=\ENn, kCPY=\ENs, kCRT=\ENt, kDL=\ENv, kEXT=\ENw, kFND=\ENx, kHLP=\ENy, kOPT=\ENz, ka3=\EOs, kb2=\EOr, kbs=^H, kc1=\EOq, kcan=\EOm, kclo=\ENc, kclr=\ENa, kcmd=\EOu, kcub1=\E[D, kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A, kdch1=\E[P, kend=\E[9, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf2=\E[12~, kf3=\E[13~, kf4=\E[14~, kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, kfnd=\ENf, khlp=\ENh, khome=\E[8, khts=\ENb, kich1=\E[2~, kmov=\ENi, kmrk=\ENm, kmsg=\ENe, knp=\E[6~, kopn=\ENo, kopt=\ENk, kpp=\E[5~, kref=\ENl, kres=\ENp, krfr=\ENg, krpl=\ENr, krst=\ENj, ksav=\ENq, kslt=\EOM, ktbc=\ENd, kund=\ENu, rc=\E8, rev=\E[7m, ri=\EM, rmacs=^O, rmam=\E[?7l, rmkx=\E>, rmso=\E[m, rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H, rs2=@, sc=\E7, setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, sgr=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m, sgr0=\E[m, smacs=^N, smam=\E[?7h, smkx=\E=, smso=\E[7m, tbc=\E[3g,
stty shows the following:
stty Name: /dev/ttyp0 Type: pseudo Opens: 2 +edit +echok +echonl +osflow intr=^C quit=^\ erase=^? kill=^U eof=^D start=^Q stop=^S susp=^Z lnext=^V min=01 time=00 pr1=^[ pr2=5B left=44 right=43 up=41 down=42 ins=40 del=50 home=48 end=59
-
Gilles 'SO- stop being evil' over 11 years
-
user3330406 over 11 yearsI have actually already seen both of those links, and I have tried to modify
kshrc
to no avail. I getsh: /etc/kshrc[21]: trap: bad signal KEYBD
I don't have another shell option unfortunately. I don't know if this is a problem with the PDKSH or with QNX or both. I do know what key combinations will cause what I want. I just need to know the syntax to map them to the appropriate keys. -
Gilles 'SO- stop being evil' over 11 yearsThe Delete key works for me with Pdksh (same version, it hasn't been maintained since the last century) under Linux. What does
bind | grep prefix
show for you? Andbind | grep '[^ -~]'
? -
user3330406 over 11 years@Gilles I updated with the results of your bind commands. Could it be my PuTTy settings? I appreciate your help. :-)
-
Gilles 'SO- stop being evil' over 11 yearsAFAIK
bind '^[[3~'='delete-char-forward'
should have worked. I don't understand where those non-ASCII characters are coming from (they're not ESC+foo sequences with the 8th bit set, nor latin1/utf8 confusions thereof). Does `bind '^X3~=delete-char-forward' work? -
Gilles 'SO- stop being evil' over 11 yearsMmmm, overwrite the character under the cursor with a ~? That's weird. Please post the complete output from
bind
. Is there a~/.kshrc
or a$ENV
? -
user3330406 over 11 yearsNew output is attached as Update 3. Also
bind '^X3~=delete-char-forward'
does not work. -
Kingsley over 5 yearsWith linux <-> solaris, it's
delete-char
(no -forward), e.g.:bind '"\e[3~": delete-char'
-
Janac Meena over 6 yearsI can confirm that this works in Conemu + Cygwin as well.
-
Milk over 4 yearsArticle is a dead link
-
a_girl almost 3 yearsDo you know how to make ssh use this "rxvt" option?