Overwrite last line on terminal

后端 未结 6 946
耶瑟儿~
耶瑟儿~ 2020-12-23 02:21

My bash-script looks as following:

echo \"Description:\"
while [ $finishInput -eq 0 ]; do
read tmp
desc=\"$desc\"$\'\\n\'\"$tmp\"
if [ -z \"$tmp\" ]; then
fi         


        
6条回答
  •  粉色の甜心
    2020-12-23 02:45

    Found a great guide on escape sequences and wanted to expand on some of the discussions here.

    When you write out to a terminal, you move an invisible cursor around, much like you do when you write in any text editor. When using echo, it will automatically end the output with a new line character which moves the cursor to the next line.

    $ echo "Hello" && echo " World"
    Hello
     World
    

    You can use -n to prevent the new line and if you echo again after this, it will append it to the end of that line

    $ echo -n "Hello" && echo " World"
    Hello World
    

    The cursor remains where it was so, on it's own, we can't use -n to overwrite the previous line, we need to move the cursor to the left. To do that we need to give it an escape sequence, which we let echo know we're going to use with -e and then move the cursor by providing a return carriage \r which puts the cursor at the beginning of the line.

    $ echo -n "Hello" && echo -e "\rWorld"
    World
    

    That may look like it worked, but see what happens with

    $ echo -n "A longer sentance" && echo -e "\rShort sentance"
    Short sentancence
    

    See the extra characters? Simply writing over the line only changes the characters where we wrote them.

    To fix this, the accepted answer above uses the escape character \e[0K to erase everything after the cursor, after the cursor has moved left. i.e. \r move to beginning \e[0K erase to end.

    $ echo -n "A longer sentance" && echo -e "\r\e[0KShort sentance"
    Short sentance
    

    Important \e to begin escape sequences works in zsh but not in sh and not necessarily in bash, however \033 works in all of them. If you want your script to work anywhere, you should preference \033

    $ echo -n "A longer sentance" && echo -e "\r\033[0KShort sentance"
    Short sentance
    

    But escape characters can provide even more utility. For example \033[1A moves the cursor to the previous line so we don't need the -n on the previous echo:

    $ echo "A longer sentance" && echo -e "\r\033[1A\033[0KShort sentance"
    Short sentance
    

    \r move to the beginning \033[1A move up \033[0K erase to the end

    Finally, this is all a bit messy in my book, so you can turn this into a function:

    overwrite() { echo -e "\r\033[1A\033[0K$@"; }
    

    Using $@ just puts all the parameters of the function into the string

    $ echo Longer sentance && overwrite Short sentence
    Short sentence
    

    Hope that helps people who want to know a bit more.

提交回复
热议问题