2

Here are my tries:

enter image description here

The last one worked, but it breaks copy-pasting (adding a lot of spaces when copied). Is there a better way?

Copyable text:

$ PS1='\['$'\x1b[0m\]$ '
$ echo -e "\x1b[41;37mWarning text\x1b[0m"; echo Normal text
Warning text
Normal text
$ echo -ne "\x1b[41;37mWarning text"$'\n'"\x1b[0m"; echo Normal text
Warning text
Normal text
$ echo -ne "\x1b[41;37mWarning text"$'\n'"\x1b[47;30m"; tr </dev/zero \\0 \ |head -c 80; echo -ne "\x1b[A";  echo Normal text
Warning text
Normal text                                                                     
$ 
$ t="Warning text";echo -ne "\x1b[41;37m";echo -n "$t";{ tr </dev/zero \\0 \ |head -c $(bc <<<"$(stty -a <&3|grep -Po '(?<=columns )[0-9]+')-$(wc -c<<<"$t")+1"); } 3<&0;echo -e "\x1b[0m";echo "Normal text"
Warning text                                                                    
Normal text
$ 
  • 1
    What terminal/shell is that? I can see the point in using a picture to show the output in this case, but it makes it impossible for us to copy+paste your commands, so I might have mistyped something (even though I was careful and checked), but whenever I include a $ like that it is echo'ed to my terminal. – Henrik Jun 24 '16 at 14:59
2

Found the solution myself (in this related question). Use this:

echo -e '\x1b[41;37mWarning text\x1b[K\x1b[0m';echo Normal text

The documentation says about \x1b[K:

       K   EL        Erase line (default: from cursor to end of line).
                     ESC [ 1 K: erase from start of line to cursor.
                     ESC [ 2 K: erase whole line.
2

Clearing to the end of the line will use the current background color with xterm and Linux console, as well as terminals which copy that behavior. In ncurses that is referred to as the background color erase (bce) capability. When the feature is supported, this provides a way to keep the background for the currently-edited line have a given color.

However:

  • It is less useful when editing a wrapped line.
  • There are some differences with the rxvt/urxvt terminals: the related erase-character (ech) capability does not use the background color. Your shell may use that when editing a line.
  • Not all terminals use the current background color when scrolling (as xterm and Linux console do).

Further reading:

2

How about this:

printf '\e[41m%-*s\e[0m\n' $COLUMNS 'Warning text'

You could also make it a function to take arguments, add color variables, etc:

linecolor () { printf '\e[41m%-*s\e[0m\n' $COLUMNS "$1"; }

usage:

linecolor 'Warning text'
0

If an extra initial blank line is acceptable:

echo -e "\x1b[41;37m\n\x1b[0m\x1b[41;37mWarning\x1b[0m"; echo "Normal"

seems to work.

The only explanation I can come up with for the behaviour I see is that it comes down to how the terminal determines which background colour to use for a new line, that would make it likely to work differently if you use another terminal than the xterm I use.

I think using printf makes you last method a little more readable, so even though this still break copy-pasting, here goes:

printf "\x1b[41;37m%-$(stty size | cut -d' ' -f2)s\x1b[0m\n" hello; echo world; echo test

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.