130

Something I have noticed in Ubuntu for a long time that has been frustrating to me is when I am typing a command at the command line that gets longer (wider) than the terminal width, instead of wrapping to a new line, it goes back to column 1 on the same line and starts over-writing the beginning of my command line. (It doesn't actually overwrite the actual command, but visually, it is overwriting the text that was displayed).

It's hard to explain without seeing it, but let's say my terminal was 20 characters wide (Mine is more like 120 characters - but for the sake of an example), and I want to echo the English alphabet. What I type is this:

echo abcdefghijklmnopqrstuvwxyz

But what my terminal looks like before I hit the key is:

pqrstuvwxyzghijklmno

When I hit enter, it echos

abcdefghijklmnopqrstuvwxyz

so I know the command was received properly. It just wrapped my typing after the "o" and started over on the same line.

What I would expect to happen, if I typed this command in on a terminal that was only 20 characters wide would be this:

echo abcdefghijklmno
pqrstuvwxyz

Background: I am using bash as my shell, and I have this line in my ~/.bashrc:

set -o vi

to be able to navigate the command line with VI commands. I am currently using Ubuntu 10.10 server, and connecting to the server with Putty.

In any other environment I have worked in, if I type a long command line, it will add a new line underneath the line I am working on when my command gets longer than the terminal width and when I keep typing I can see my command on 2 different lines. But for as long as I can remember using Ubuntu, my long commands only occupy 1 line.

This also happens when I am going back to previous commands in the history (I hit Esc, then 'K' to go back to previous commands) - when I get to a previous command that was longer than the terminal width, the command line gets mangled and I cannot tell where I am at in the command.

The only work-around I have found to see the entire long command is to hit "Esc-V", which opens up the current command in a VI editor.

I don't think I have anything odd in my .bashrc file. I commented out the "set -o vi" line, and I still had the problem.

I downloaded a fresh copy of Putty and didn't make any changes to the configuration - I just typed in my host name to connect, and I still have the problem, so I don't think it's anything with Putty (unless I need to make some config changes)

Has anyone else had this problem, and can anyone think of how to fix it?

Edit

It was my .bashrc file. I've copied the same profile from machine to machine, and I used special characters in my $PS1 that are somehow throwing it off. I'm now sticking with the standard bash variables for my $PS1.

Thanks to @ændrük for the tip on the .bashrc!

...End Edit...

Hugo
  • 146
BrianH
  • 1,403

8 Answers8

175

Make sure all non-printable bytes in your PS1 are contained within \[ \]. Otherwise, bash will count them in the length of the prompt. It uses the length of the prompt to determine when to wrap the line.

For example, here bash counts the prompt as 19 columns wide, while the prompt displayed by the terminal is only 10 columns wide (My prompt written in cyan, and > written in default color):

PS1='\e[36mMy prompt\e[0m>'         # bash count: 19, actual: 10

while here it only counts the prompt as 10 columns wide because it ignores the bytes between the special \[ and \] escapes:

PS1='\[\e[36m\]My prompt\[\e[0m\]>' # bash count: 10, actual: 10

For good practice though, use tput to generate the terminal escapes rather than hard coding them:

cyan=$(tput setaf 6) # \e[36m
reset=$(tput sgr0)   # \e[0m
PS1='\[$cyan\]My prompt\[$reset\]>'

For more information see the following resources

bash prompt: http://mywiki.wooledge.org/BashFAQ/053

tput: https://linuxcommand.org/lc3_adv_tput.php

Amol
  • 103
geirha
  • 47,279
60

I guess you have configured your PS1 with colors, right?

Just make sure you have \[ inside your PS1 quote preceding your color set

For example:

PS1='\[\e[0;32m\u@\w/:\[\e[m '
wjandrea
  • 14,504
17

I had a similar issue, and finally found a simple solution.

Add following line in your .bashrc file:

COLUMNS=250

Then type source ~/.bashrc to get the desired effect.

cat
  • 1,712
Deboshree
  • 179
7

A simple thing to do would be to add the following line before setting the PS1:

stty columns 1000

For example,

stty columns 1000
PS1='\[\e[0;32m\u@\w/:[\e[m '

however this does affect other unix commands like ls and man.

Gennady
  • 89
5

I had the same issue with a custom coloured prompt, even though I contained colour codes within \[ and \] delimiters. It turns out that bash has problems echoing colours from inside a function. I ended up just using variables for my prompt, and though my .bashrc is a little less elegant, everything works nicely now.

reentim
  • 51
0

So I just had the same issue with a slight twist on it and I thought I would share my solution too, just to add my little nuance :D

My initial PS1 was

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$"

The problem I had was that I was trying to change my terminal title as well as the command prompt. The way I did this was by adding \[\033]0;\]Title\a to the PS1 variable.

So now my PS1 was:

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[\033]0;\]Title\a"

This messed up the line wrapping for me. I finally figured out that bash doesn't seem to like having \a at the end. To circumvent this, I put the title in a variable, which seemed to fix it.

TITLE="\033]0;Title\a"
PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[$TITLE\]"
0

\[ and \] didn't work for me. I guess there was something different about how I was generating the prompt (from an external program), or because my prompt was "dynamic".

After reading this I found that you can actually escape the color codes with the 0x01 and 0x02 bytes.

e.g. I'm using a special version of Chalk and I wrap the colors using this:

const Chalk = require('@nasc/chalk');

const chalk = new Chalk.constructor({
  wrapper: {
    pre: '\1',
    post: '\2',
  }
});
mpen
  • 2,236
0

I had this problem when connected in tmux. The problem was that I had an ipython session in the background (ctrl + z) and that somehow broke line wrapping. As soon as I terminated it (fg, ctrl+d+d) my terminal started working properly

So check for any stopped interactive prompts.