bash script, erase previous line?

前端 未结 6 1272
暗喜
暗喜 2021-01-31 10:31

In lots of Linux programs, like curl, wget, and anything with a progress meter, they have the bottom line constantly update, every certain amount of time. How do I do that in a

相关标签:
6条回答
  • 2021-01-31 10:58

    man terminfo(5) and look at the "cap-nam" column.

    clr_eol=$(tput el)
    while true
    do
        printf "${clr_eol}your message here\r"
        sleep 60
    done
    
    0 讨论(0)
  • 2021-01-31 11:07

    Small variation on linuts' code sample to move the cursor not to the beginning, but the end of the current line.

    {
      for pc in {1..100}; do
        #echo -ne "$pc%\033[0K\r"
        echo -ne "\r\033[0K${pc}%"
        sleep 1
      done
      echo
    }
    
    0 讨论(0)
  • 2021-01-31 11:07

    To actually erase previous lines, not just the current line, you can use the following bash functions:

    # Clears the entire current line regardless of terminal size.
    # See the magic by running:
    # { sleep 1; clear_this_line ; }&
    clear_this_line(){
            printf '\r'
            cols="$(tput cols)"
            for i in $(seq "$cols"); do
                    printf ' '
            done
            printf '\r'
    }
    
    # Erases the amount of lines specified.
    # Usage: erase_lines [AMOUNT]
    # See the magic by running:
    # { sleep 1; erase_lines 2; }&
    erase_lines(){
            # Default line count to 1.
            test -z "$1" && lines="1" || lines="$1"
    
            # This is what we use to move the cursor to previous lines.
            UP='\033[1A'
    
            # Exit if erase count is zero.
            [ "$lines" = 0 ] && return
    
            # Erase.
            if [ "$lines" = 1 ]; then
                    clear_this_line
            else
                    lines=$((lines-1))
                    clear_this_line
                    for i in $(seq "$lines"); do
                            printf "$UP"
                            clear_this_line
                    done
            fi
    }
    

    Now, simply call erase_lines 5 for example to clear the last 5 lines in the terminal.

    0 讨论(0)
  • 2021-01-31 11:16

    You can also use tput cuu1;tput el (or printf '\e[A\e[K') to move the cursor up one line and erase the line:

    for i in {1..100};do echo $i;sleep 1;tput cuu1;tput el;done
    
    0 讨论(0)
  • 2021-01-31 11:21

    printf '\r', usually. There's no reason for cursor addressing in this case.

    0 讨论(0)
  • 2021-01-31 11:22
    {
      for pc in $(seq 1 100); do
        echo -ne "$pc%\033[0K\r"
        usleep 100000
      done
      echo
    }
    

    The "\033[0K" will delete to the end of the line - in case your progress line gets shorter at some point, although this may not be necessary for your purposes.

    The "\r" will move the cursor to the beginning of the current line

    The -n on echo will prevent the cursor advancing to the next line

    0 讨论(0)
提交回复
热议问题