在Shell脚本中显示进度条

注意:如果你使用的是Ubuntu,第一行中的程序路径一定要写/bin/bash而不是/bin/sh;其他版本的两者皆可,因为/bin/sh只是/bin/bash的一个软链接;在Ubuntu中/bin/sh是/bin/dash的软链接。

  • 方法一

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    #!/bin/bash
     
    b=''
    for ((i=0;$i<=100;i+=2))
    do
           printf "progress:[%-50s]%d%%r" $b $i
           sleep 0.1
           b=#$b
    done
    echo

  • 方法二

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    
    #!/bin/bash
     
    # progbar3.sh
    # Simulate a progress bar with colors
    # Author: Sofiane Cherchalli
    # Date: 24 Oct 2010
     
    dot="."
    a=( '/' '-' '' '|' )
    per=0
     
    do_sleep() {
     local t="$1"
     which perl &>/dev/null && sleep_cmd="perl -e 'select(undef,undef,undef,$t)'" || sleep_cmd="sleep $t"
     eval "$sleep_cmd"
    }
     
    wait_4_esc() {
     local msg="Please, press two times ESC key to start demo: "
     while read -s -n2 -p "$msg" key; do
       printf "n"
       [ "$key" = "`echo $'x1bx1b'`" ] && break || msg="What??? I said Press TWO TIMES ESC key on your keyboard to start demo!. Is my english that bad? :( . Try again: "
     done
    }
     
    # main
    wait_4_esc
    printf "nThanks! :) . Starting demo right now...n"
    while [ "$per" -le "100" ]; do
     showper=`expr $per % 10`
     if [ "$showper" = "0" ]; then
       if [ "$per" -le "30" ]; then
         printf "e[31m%s" "${per}%"
       elif [ "$per" -gt "30" -a "$per" -le "70" ]; then
         printf "e[33m%s" "${per}%"
       else
         printf "e[32m%s" "${per}%"
       fi
     fi
     
     for ((i=0; i<${#a[@]}; i++)); do
       printf "e[0m%s" "${a[${i}]}"
       do_sleep .1
       printf "e[1De[0K"
     done
     
     [ "$per" -lt "100" ] && printf "e[0m%s" "$dot"
     per=`expr $per + 1`
    done
    printf "e[0mnHYLI!nn"
  • 方法三

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    
    #!/bin/bash
     
    # progbar6.sh
    # Simulate a progress bar with colors
    # Author: Sofiane Cherchalli
    # Date: 24 Oct 2010
     
     
    do_sleep() {
      local t="$1"
      which perl &>/dev/null && sleep_cmd="perl -e 'select(undef,undef,undef,$t)'" || sleep_cmd="sleep $t"
      eval "$sleep_cmd"
    }
     
    show_prog_bar() {
      local c="$1" # Character to use to draw progress bar
      local v=$2 # Percentage 0<= value <=100
     
      local pbl=50 # Progress bar length in characters
      local r=`expr 100 / $pbl` # Ratio between percentage value and progress bar length
      local p="$v%" # Percentage value to display in the middle of progress bar
      local l=${#p} # Length of string to display
      local pbs="" # Progress bar string
      local k=`expr ( $pbl - $l ) / 2` # Position where to substitute in progress bar string
      local n1=`expr $v / $r`
      local n2=`expr $pbl - $n1`
     
      for (( i=0; i<$pbl; i++ )); do
        pbs="${pbs}${c}"
      done
     
      pbs=`echo "$pbs" | sed 's/^(.{'"${k}"'})(.{'"${l}"'})(.*$)/1'"${p}"'3/'`
     
      printf "re[44m%se[41m%s" "${pbs:0:$n1}" "${pbs:$n1:$n2}"
    }
     
    # Simulate a child process doing some work. Progress percentage is wtitten to a temp file
    some_work() {
      local a=(0 3 5 20 37 51 67 80 98 100) # Simulate some progress values done by worker
      local sl=(1 .3 .5 3 .5 .9 1 .8 1 3) # Simulate some work times
     
      for ((i=0; i> /tmp/progbar
        do_sleep ${sl[${i}]}
      done
    }
     
    wait_4_esc() {
      local msg="Please, press two times ESC key to start demo: "
      while read -s -n2 -p "$msg" key; do
        printf "n"
        [ "$key" = "`echo $'x1bx1b'`" ] && break || msg="What??? I said Press TWO TIMES ESC key on your keyboard to start demo!. Is my english that bad? :( . Try again: "
      done
    }
     
    # main
    wait_4_esc
    > /tmp/progbar
     
    some_work &
    pid=$!
     
    per=0
    printf "nThanks! :) . Starting demo right now...n"
    while read line || [ "$per" -lt "100" ]; do
      if [ -n "$line" ]; then
        per=$line
        show_prog_bar " " $per
      fi
      do_sleep .1
    done < /tmp/progbar
     
    printf "e[0mnHYLI!nn"