bichonfrise74 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I have this little script and STDIN seems to be behaving differently for different Linux environments specifically when I enter a backspace.
#!/usr/bin/perl -w use strict; print "Enter: "; my $input = <STDIN>;
When I tested this on an Ubuntu 8.04, I see this output.
[home]$ perl test.pl Enter: test^H^H
The ^H is referring to a backspace. Now, when I tested this script on a RedHat Enterprise 3 and hit backspace, then it works as what I would expect (performs the backspace).

Anyone seen this before and ideas on how to remedy this? Thanks.

Replies are listed 'Best First'.
Re: STDIN Odd Bevahior in Linux Environments
by MidLifeXis (Monsignor) on Sep 23, 2009 at 21:49 UTC

    Terminal setting. From your terminal, type

    stty erase BACKSPACE-KEY

    Replace BACKSPACE-KEY with you pressing the backspace key.

    Your shell is not expecting the character that your terminal is sending to perform the backspace function.

    Update: Fixed typo.

    --MidLifeXis

    Please consider supporting my wife as she walks in the 2009 Alzheimer's Walk.

Re: STDIN Odd Bevahior in Linux Environments
by moritz (Cardinal) on Sep 23, 2009 at 21:51 UTC

    Is this related to perl at all? Or does the same happen when you just start cat, type a few characters and then hit backspace?

    I guess the terminal is not configured as you'd like it to be.

    Perl 6 - links to (nearly) everything that is Perl 6.
      No, it isn't related to perl, but it is understandable that you don't know that.

      What it is related to is the terminal "emulator" you are using. They vary somewhat, as does the means of dealing with this issue. The reason is that the emulator can capture and modify various key codes.

      For example, I use the XFCE Terminal. If I go to Preferences->advanced, there is the option: "Backspace key generates" and the choices include Control-H, which is what you are getting (they also include "Escape sequence", which would be the normative ascii value of backspace, and ascii del, which would make backspace == delete).

      Probably you are using the gnome-terminal, but I think if you look around in it you will be able to find something similar. Most likely, your Ubuntu and your RedHat are configured differently. You may have more luck on a linux forum, many people there will understand perl and be more familiar with little OS details like this.

      MidLifeXis's suggestion is probably a good one, since the shell is intermediary between the terminal and perl.

        This is not just a terminal emulator issue.

        Terminal settings on Unix was designed at a time where terminals were hardware, so terminal settings must be set on the server side. Or at least unix side settings must match terminal side settings.

        You have two sets of settings on the unix side:

        • line settings defined with stty for the most important control keys (break, sleep, pause...)
        • TERM environment variable which tells all settings for curses applications that use it. This variable is the name of a file in /usr/share/terminfo

        If your TERM variable is correctly set to match your terminal emulator, you can use the terminfo settings to set the line settings in your profile:

        [[ -n "$TERM" ]] && stty erase "$(tput kbs)" susp "$(tput kspd)"
      I think it might not be related to Perl but thought people might have seen this.

      Anyway, if I start cat and type a few characters and hit backspace, then it works fine on Ubuntu 8.04 (this is the OS where I'm having the backspace problem).
Re: STDIN Odd Bevahior in Linux Environments
by liverpole (Monsignor) on Sep 23, 2009 at 21:52 UTC
    Hi bichonfrise74,

    I've not seen that before, but if you try running the script utility (which spawns a new shell, and then records all I/O until you exit the shell, saving it to a specified textfile, or typescript by default), it might give you more clues about what's happening.

    For example:

    [liverpole@myhost ~]% cat example.pl #!/usr/bin/perl -w use strict; print "Enter: "; my $input = <STDIN>; [liverpole@myhost ~]% script output Script started, file is output liverpole@myhost# ./example.pl Enter: tes liverpole@myhost# exit exit Script done, file is output [liverpole@myhost ~]% cat output Script started on Wed Sep 23 17:46:45 2009 liverpole@myhost# ./example.pl Enter: tes liverpole@myhost# exit exit Script done on Wed Sep 23 17:47:08 2009

    In the above example, the backspace key worked as expected, which you can see very clearly when you edit the script file "output", as the line with the backspace is revealed to be:

    Enter: test^H ^H^M

    Clearly it's doing a backspace, followed by a space (to erase the final 't' of 'text'), followed by another backspace.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      This is what I see when I do cat output...
      Script started on Wed 23 Sep 2009 03:20:17 PM PDT home:~$ perl 33.pl Enter: test^H^Hhello^H^Hm^H home:~$ exit exit Script done on Wed 23 Sep 2009 03:20:29 PM PDT
      This is what I see when I run vi output...
      Script started on Wed 23 Sep 2009 03:20:17 PM PDT ^[]0;home: ~^Ghome:~$ perl 33.pl^M Enter: test^H^Hhello^H^Hm^H^M ^[]0;home: ~^Ghome:~$ exit^M exit^M Script done on Wed 23 Sep 2009 03:20:29 PM PDT
      It looks like only ^M (enter key) is working properly and ^H is not. Hmm... does this mean that this is not a Perl-related problem?
Re: STDIN Odd Bevahior in Linux Environments
by Bloodnok (Vicar) on Sep 23, 2009 at 22:31 UTC
    As moritz and MidLifeXis have both suggested, it looks like your key mappings may not be what you think/would like and changing them/it would appear to present the best solution to your problem.

    The quick way to reset _all_ key mappings for the session is to use stty sane which, in most cases, will reset the mappings to, as it [the command argument] suggests, a 'reasonably' sane setting - use c> man stty</c> for further details.

    A user level that continues to overstate my experience :-))
Re: STDIN Odd Bevahior in Linux Environments
by walkingthecow (Friar) on Sep 24, 2009 at 05:27 UTC
    Also, you may want to check your shell, or your environment. I know ksh often does this, and with bash I have never had this issue. You can try 'set -o vi' and maybe that will stop it from happening, or stty erase <then hit backspace> so it looks like stty erase ^H<enter>. Or do a chsh and change to bash.
      I would recommend treading carefully with the 'set -o vi' as it can be a real pain if you are not prepared for it. For example, if you are used to pressing the up arrow for your command history, set -o vi will take this away. You will have to use your vi keys for this (escape k and j for up and down). I prefer 'set -o emacs' to allow me to use the arrow keys for my history.
      As for the ^H, as others have suggested stty erase ^H should fix the problem in your current terminal. You should be able to set it in your .bashrc, so that it will be persistent across sessions.
        vi-mode in zsh 4 works very much like in a vi-like editor (after setting 4-5 custom key bindings for insert mode). In ksh93, bash 3 (& below), it is best to stick with emacs-mode as vi-mode support is horrrid with too many exceptions (wrt an editor). Situation may have changed in bash 4, but I doubt that.
Re: STDIN Odd Bevahior in Linux Environments
by Porculus (Hermit) on Sep 24, 2009 at 20:29 UTC

    We can make this related to Perl very easily:

    Have you considered using Term::ReadLine? It's nearly always preferable for interactive programs, as it can give you command-line editing and history.

    On Linux systems, having Term::ReadLine::Gnu installed is highly recommended, as it will pick up your settings from .inputrc and so forth.