How to add a progress bar to a shell script?

后端 未结 30 2789
情歌与酒
情歌与酒 2020-11-22 05:48

When scripting in bash or any other shell in *NIX, while running a command that will take more than a few seconds, a progress bar is needed.

For example, copying a b

30条回答
  •  爱一瞬间的悲伤
    2020-11-22 06:33

    Here is how it might look

    Uploading a file

    [##################################################] 100% (137921 / 137921 bytes)
    

    Waiting for a job to complete

    [#########################                         ] 50% (15 / 30 seconds)
    

    Simple function that implements it

    You can just copy-paste it to your script. It does not require anything else to work.

    PROGRESS_BAR_WIDTH=50  # progress bar length in characters
    
    draw_progress_bar() {
      # Arguments: current value, max value, unit of measurement (optional)
      local __value=$1
      local __max=$2
      local __unit=${3:-""}  # if unit is not supplied, do not display it
    
      # Calculate percentage
      if (( $__max < 1 )); then __max=1; fi  # anti zero division protection
      local __percentage=$(( 100 - ($__max*100 - $__value*100) / $__max ))
    
      # Rescale the bar according to the progress bar width
      local __num_bar=$(( $__percentage * $PROGRESS_BAR_WIDTH / 100 ))
    
      # Draw progress bar
      printf "["
      for b in $(seq 1 $__num_bar); do printf "#"; done
      for s in $(seq 1 $(( $PROGRESS_BAR_WIDTH - $__num_bar ))); do printf " "; done
      printf "] $__percentage%% ($__value / $__max $__unit)\r"
    }
    

    Usage example

    Here, we upload a file and redraw the progress bar at each iteration. It does not matter what job is actually performed as long as we can get 2 values: max value and current value.

    In the example below the max value is file_size and the current value is supplied by some function and is called uploaded_bytes.

    # Uploading a file
    file_size=137921
    
    while true; do
      # Get current value of uploaded bytes
      uploaded_bytes=$(some_function_that_reports_progress)
    
      # Draw a progress bar
      draw_progress_bar $uploaded_bytes $file_size "bytes"
    
      # Check if we reached 100%
      if [ $uploaded_bytes == $file_size ]; then break; fi
      sleep 1  # Wait before redrawing
    done
    # Go to the newline at the end of upload
    printf "\n"
    

提交回复
热议问题