How to add a progress bar to a shell script?

后端 未结 30 2665
情歌与酒
情歌与酒 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:39

    Based on the work of Edouard Lopez, I created a progress bar that fits the size of the screen, whatever it is. Check it out.

    It's also posted on Git Hub.

    #!/bin/bash
    #
    # Progress bar by Adriano Pinaffo
    # Available at https://github.com/adriano-pinaffo/progressbar.sh
    # Inspired on work by Edouard Lopez (https://github.com/edouard-lopez/progress-bar.sh)
    # Version 1.0
    # Date April, 28th 2017
    
    function error {
      echo "Usage: $0 [SECONDS]"
      case $1 in
        1) echo "Pass one argument only"
        exit 1
        ;;
        2) echo "Parameter must be a number"
        exit 2
        ;;
        *) echo "Unknown error"
        exit 999
      esac
    }
    
    [[ $# -ne 1 ]] && error 1
    [[ $1 =~ ^[0-9]+$ ]] || error 2
    
    duration=${1}
    barsize=$((`tput cols` - 7))
    unity=$(($barsize / $duration))
    increment=$(($barsize%$duration))
    skip=$(($duration/($duration-$increment)))
    curr_bar=0
    prev_bar=
    for (( elapsed=1; elapsed<=$duration; elapsed++ ))
    do
      # Elapsed
    prev_bar=$curr_bar
      let curr_bar+=$unity
      [[ $increment -eq 0 ]] || {  
        [[ $skip -eq 1 ]] &&
          { [[ $(($elapsed%($duration/$increment))) -eq 0 ]] && let curr_bar++; } ||
        { [[ $(($elapsed%$skip)) -ne 0 ]] && let curr_bar++; }
      }
      [[ $elapsed -eq 1 && $increment -eq 1 && $skip -ne 1 ]] && let curr_bar++
      [[ $(($barsize-$curr_bar)) -eq 1 ]] && let curr_bar++
      [[ $curr_bar -lt $barsize ]] || curr_bar=$barsize
      for (( filled=0; filled<=$curr_bar; filled++ )); do
        printf "▇"
      done
    
      # Remaining
      for (( remain=$curr_bar; remain<$barsize; remain++ )); do
        printf " "
      done
    
      # Percentage
      printf "| %s%%" $(( ($elapsed*100)/$duration))
    
      # Return
      sleep 1
      printf "\r"
    done
    printf "\n"
    exit 0
    

    Enjoy

提交回复
热议问题