Bash: messed up display for long lines

bashbashrcUbuntu

I am using the GNU bash, version 4.4.0(1) on Ubuntu 16.04.

When I enter long lines in my bash, its display is messed up.

For example, assuming I am in ~/test/test/test/test/test/test/test and I enter echo "The quick brown fox jumps over the lazy doggo" it looks like this:
enter image description here
This is halfway okay, even though I would prefer a wrapped display and I could do without the doubling of the line.

The problem is when I now fix the sentence by pressing backspace three times plus double quotes once, the display looks like this:
enter image description here

The o" at the end is a display error, as confirmed by pressing enter:
enter image description here

You can see that the desired sentence with dog instead of doggo is printed. It is printed in green though, for whatever reason.

All of this becomes even worse when I now enlarge and shrink the terminal window a few times. The content of the terminal then gets randomly copied and concatenated throughout the terminal:
enter image description here
(The long black boxes are random concatenations of the contents of my prompt.)

I figure all of this could be related to the ~/.bashrc, even though I just did cp /etc/skel/.bashrc ~/. Anyway, here it is:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
    # We have color support; assume it's compliant with Ecma-48
    # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
    # a case would tend to support setf rather than setaf.)
    color_prompt=yes
    else
    color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

Upon removing ~/.bashrc, I get the following:
(I am using the command echo "This is a really long sentence, even long than a sentence containing all letters of the alphabet" to make up for the shorter prompt)

First, everything is fine:
enter image description here

Upon deleting a few words, I get some leftovers at the end of the line:
enter image description here

Furthermore, if I keep pressing backspace, I can even delete parts of the prompt:
enter image description here

After pressing enter (and fixing the end of the command to [...], ev"), and upon resizing, I get the usual mess:
enter image description here

Best Answer

Your prompt contains colors (and maybe other non-printables).

In bash, you can surround the parts with \[ and \] to tell bash to ignore those parts to calculate the length of the prompt.

Ex:

PS1="\e[33mthis is green\e[0m this is normal"
# should be done as:
PS1="\[\e[33m\]this is green\[\e[0m\] this is normal"

The 2nd one has \[ and \] around each part that, while changing the color, doesn't add any visible character in the display, thus should not be counted when calculating the placement of characters on the prompt.

If you modified PS1, make sure you didn't put within \[ and \] visible characters. If you did, get them outside of those.

Another thing : You may want to do shopt -q -s checkwinsize to make sure the terminal size is updated when it is resized.

And you seem to be using a setting that shows only the end of the currently entered command line (similar as what ksh does... are you sure you use bash?) : I'll look into what option can change this, but I don't know it yet.

edit

In chat we also discussed:

set -o emacs  #he was in vi mode
set -o posix  #he was in posix=no mode

but in the end it seems what worked was get rid of ~/.inputrc (which he did, it may have contained something wrong but I don't know what was in it, nor did I asked to delete it ^^ just renaming it (or fixing its content) would have helped...)

Related Question