Search code examples
linuxbashterminalconsoletty

bash command line can not read command properly


I have a problem about bash terminal, and it made me crazy, and i don't know why.
It is about the terminal, let me describe it as below:
At first the prompt is like:

[12:00]ruan:~>  

But when i input characters consecutively (for example, assume i input a lot of A), the weird thing happened:

AAA:00]ruan:~ > AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  

As you can see, character i input starts from the beginning of the line, which made my command unreadable. I don't know how can this happen. Is it related to stty, inputrc or something else?
/br
ruan

my tty config is like:

:)[11:38]ruan:~ > stty -a
speed 38400 baud; 25 rows; 80 columns;
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

i have setup PS1 like:

NORMAL="\033[0m"
RED="\033[0;31m"
RED_BOLD="\033[1;31m"
GREEN="\033[0;32m"
GREEN_BOLD="\033[1;32m"
YELLOW="\033[0;33m"
YELLOW_BOLD="\033[1;33m"
BLUE="\033[0;34m"
BLUE_BOLD="\033[1;34m"
MAGENTA="\033[0;35m"
MAGENTA_BOLD="\033[1;35m"
CYAN="\033[0;36m"
CYAN_BOLD="\033[1;36m"

function smile_or_frown() {
    [[ $? = 0 ]] && echo -e "${CYAN_BOLD}:)" || echo -e "${MAGENTA_BOLD}:("
}
export PS1="\$(smile_or_frown)$BLUE_BOLD[\A]$GREEN_BOLD\u:$RED_BOLD\w$YELLOW_BOLD\$(parse_git_branch)$NORMAL > "

Solution

  • You have to enclose all ANSI escape sequences in \[ .. \] to signal to Bash that these don't take up space on the terminal.

    They have to be in the format string itself, and can not be part of data expanded at prompt time (but can be in data expanded at assignment time).

    For example:

    export PS1="\[$BLUE_BOLD\][\A]\[$GREEN_BOLD\]\u:\[$RED_BOLD\]\w\[$YELLOW_BOLD\]\$(parse_git_branch)\[$NORMAL\] > "
    

    To make this work for smile_or_frown, you have to refactor it into two functions, one for the color and one for the text, so that you can do "\[\$(smile_color)\]\$(smile_type)"