How to display and refresh multiple lines in bash

后端 未结 5 795
孤独总比滥情好
孤独总比滥情好 2020-12-14 21:49

I am writing a installation script and would like to display the status of the script as it progresses.

example:

var1=\"pending\"
var2=\"pending\"
va         


        
相关标签:
5条回答
  • 2020-12-14 22:06

    This code should give you the idea:

    while :; do
        echo "$RANDOM"
        echo "$RANDOM"
        echo "$RANDOM"
        sleep 0.2
        tput cuu1 # move cursor up by one line
        tput el # clear the line
        tput cuu1
        tput el
        tput cuu1
        tput el
    done
    

    Use man tput for more info. To see the list of capabilities use man terminfo

    0 讨论(0)
  • 2020-12-14 22:07

    Look at this:

    while true; do echo -ne "`date`\r"; done
    

    and this:

    declare arr=(
      ">...."
      ".>..."
      "..>.."
      "...>."
      "....>"
    )
    
    for i in ${arr[@]}
    do
      echo -ne "${i}\r"
      sleep 0.1
    done
    
    0 讨论(0)
  • 2020-12-14 22:15

    This does not completely solve your problem but might help; to print the status after the execution of each command, modify PS1 like this:

    PS1='$PS1 $( print_status )'
    
    0 讨论(0)
  • 2020-12-14 22:17

    You can use the carriage return to change text on a single status line.

    n=0
    while true; do
      echo -n -e "n: $n\r"
      sleep 1
      n=$((n+1))
    done
    

    If you can put all your counters on one line

    n=0
    m=100
    while true; do
      echo -n -e "n: $n  m: $m\r"
      sleep 1
      n=$((n+1))
      m=$((m-1))
    done
    

    This technique doesn't seem to scale to multiple lines, though it does have the benefit over tput that it works on dumb terminals (like Emacs shell).

    0 讨论(0)
  • I find another solution which is not mentioned in existing answers. I am developing program for openwrt, and tput is not available by default. The solution below is inspired by Missing tput and Cursor Movement.

    - Position the Cursor:
      \033[<L>;<C>H
         Or
      \033[<L>;<C>f
      puts the cursor at line L and column C.
    - Move the cursor up N lines:
      \033[<N>A
    - Move the cursor down N lines:
      \033[<N>B
    - Move the cursor forward N columns:
      \033[<N>C
    - Move the cursor backward N columns:
      \033[<N>D
    
    - Clear the screen, move to (0,0):
      \033[2J
    - Erase to end of line:
      \033[K
    
    - Save cursor position:
      \033[s
    - Restore cursor position:
      \033[u
    

    As for your question:

    var1="pending"
    var2="pending"
    var3="pending"
    
    print_status () {
        # add \033[K to truncate this line
        echo "Status of Item 1 is: "$var1"\033[K"
        echo "Status of Item 2 is: "$var2"\033[K"
        echo "Status of Item 3 is: "$var3"\033[K"
    }
    
    while true; do 
        print_status
        sleep 1
        printf "\033[3A"    # Move cursor up by three line
    done
    
    0 讨论(0)
提交回复
热议问题