【问题标题】:Bash progress bar [duplicate]Bash进度条[重复]
【发布时间】:2012-07-21 13:27:03
【问题描述】:

我正在使用以下脚本在 whois 中浏览大量域并找到注册商(对服务器/DNS 迁移很有用),它工作正常。

但是,为了方便起见,我想在其中加入一个进度条。这是我的脚本,如果可以改进,请告诉我:

#!/bin/bash
for f in `cat /var/www/vhosts/domainlist`
 do
   if
   domain=$f
   [ "$domain" ] ;
   then
    whois $f | grep -i domainregistrar > /dev/null
     if
     [ $? -le 0 ] ;
     then
      echo $f >> our_registrar
     else
      echo $f >> external_registrar
     fi
   fi
 done
echo "Done, check our_registrar file."

我首先尝试过:http://moblog.bradleyit.com/2010/02/simple-bash-progress-bar-function.html

然后this 但没有运气。

您认为在该脚本中实现进度条的最简单方法是什么?

【问题讨论】:

    标签: bash progress-bar


    【解决方案1】:

    这是一个您可能会喜欢的精美进度条...

    #!/bin/bash
    #   Slick Progress Bar
    #   Created by: Ian Brown (ijbrown@hotmail.com)
    #   Please share with me your modifications
    # Functions
    PUT(){ echo -en "\033[${1};${2}H";}  
    DRAW(){ echo -en "\033%";echo -en "\033(0";}         
    WRITE(){ echo -en "\033(B";}  
    HIDECURSOR(){ echo -en "\033[?25l";} 
    NORM(){ echo -en "\033[?12l\033[?25h";}
    function showBar {
            percDone=$(echo 'scale=2;'$1/$2*100 | bc)
            halfDone=$(echo $percDone/2 | bc) #I prefer a half sized bar graph
            barLen=$(echo ${percDone%'.00'})
            halfDone=`expr $halfDone + 6`
            tput bold
            PUT 7 28; printf "%4.4s  " $barLen%     #Print the percentage
            PUT 5 $halfDone;  echo -e "\033[7m \033[0m" #Draw the bar
            tput sgr0
            }
    # Start Script
    clear
    HIDECURSOR
    echo -e ""                                           
    echo -e ""                                          
    DRAW    #magic starts here - must use caps in draw mode                                              
    echo -e "          PLEASE WAIT WHILE SCRIPT IS IN PROGRESS"
    echo -e "    lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk"  
    echo -e "    x                                                   x" 
    echo -e "    mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj"
    WRITE             
    #
    # Insert your script here
    for (( i=0; i<=50; i++ ))  
    do
        showBar $i 50  #Call bar drawing function "showBar"
        sleep .2
    done
    # End of your script
    # Clean up at end of script
    PUT 10 12                                           
    echo -e ""                                        
    NORM
    

    看起来像这样:

    【讨论】:

    • 我在左上角的 %:% PLEASE WAIT WHILE SCRIPT IS IN PROGRESS 看到一个奇怪的 unicode 符号,我该如何删除它?截图:i.stack.imgur.com/7JHnj.png
    • 我想我解决了这个问题,将 DRAW 更改为 DRAW(){echo -en "\033(0";} echo -en "\033%"; 是为了什么?
    • 你能解释一下这个解决方案吗?
    【解决方案2】:

    您可以使用pv,但反之亦然。

     for ... # outer loop
     do
       ...
       echo -n X
     done | pv -s $(wc -l 'your_file_list') - >/dev/null 
    

    所以你使用echo X 来表示另一部分工作何时完成并计入 通过 pv,它知道由于 -s 选项而导致的整个作业大小。

    【讨论】:

    • 我回家后看看这个:) 到目前为止干杯。
    • 这很简洁,但请记住,它将 for 循环置于子 shell 中,因此您对循环内的变量所做的任何更改都不会影响循环外的变量!跨度>
    【解决方案3】:

    你可以使用类似的东西:

    progress(){
        # example usage:
        # progress 30G 9G 30
        # 30G [================>.................................] 30% (9G)
    
        # params:
        # $1 = total value (e.g.: source size)
        # $2 = current value (e.g.: destination size)
        # $3 = percent completed
        [[ -z $1 || -z $2 || -z $3 ]] && exit  # on empty param...
    
        percent=$3
        completed=$(( $percent / 2 ))
        remaining=$(( 50 - $completed ))
    
        echo -ne "\r$1 ["
        printf "%0.s=" `seq $completed`
        echo -n ">"
        [[ $remaining != 0 ]] && printf "%0.s." `seq $remaining`
        echo -n "] $percent% ($2)  "
    }
    

    来自https://gist.github.com/ivanalejandro0/9159989

    你可以在https://github.com/ivanalejandro0/misc/blob/master/shell-scripts/copy-progress.sh看到一个使用示例

    【讨论】:

      【解决方案4】:

      将外循环改为:

      pv /var/www/vhosts/domainlist | while read f
      do
          ...
      done
      

      http://linux.die.net/man/1/pv

      或者您可以使用任何其他程序,根据文件的读取量提供进度条。

      【讨论】:

      • 我把那行放在里面,脚本仍然可以工作,但是它会立即达到 100% 并立即充满:./findregistrar.sh 1.12kB 0:00:00 [30.4MB/s] [ ================================================== ==============================‌​=================== >] 100% 所以它没有正常工作。它位于空白光标处,这在完成之前是正常的,然后当完成时,它显然会说:完成,检查 our_registrar 文件。但不清楚为什么它不起作用。
      • 我有一种感觉,这是因为它不知道 25/50/75/100 的实际定义是什么以及它何时达到 % 阶段。
      • 这可能是因为 bash 的 read 读取了整个输入然后处理它。
      • 如果我得到它来计算文件中有多少行,将其除以 10 并告诉它 =>X (或
      【解决方案5】:

      鉴于您在评论中提到您使用的是基于 debian 的系统,您可以使用whiptail。当您安装需要配置的 deb 包时,会绘制基于文本的窗口来询问您的内容;那是whiptail

      类似

      #!/usr/bin/env bash
      
      # mapfile requires bash 4
      mapfile -t domains < /var/www/vhosts/domainlist
      
      # for older bash versions, read can be used in this case.
      #IFS=$'\n' read -rd '' -a domains < /var/www/vhosts/domainlist
      
      n=${#domains[@]}
      
      for ((i=0; i < n; ++i)); do
          printf 'XXX\n\n%s\nXXX\n' "Checking ${domains[i]}"
          if whois "${domains[i]}" | grep -Fiq domainregistrar; then
              printf '%s\n' "${domains[i]}" >&3
          else
              printf '%s\n' "${domains[i]}" >&4
          fi
          printf '%d\n' $((100*i/n))
      done 3>our_registrar 4>external_registrar | whiptail --gauge "" 6 50 0
      

      【讨论】:

      • mapfile 需要 bash v4。
      • @jordanm,说得好。我相当肯定 Ubuntu 10.04 有 bash 4,但我还是用旧 bash 版本的替代方案更新了答案。
      • 是的,看起来它有 4.1:packages.ubuntu.com/lucid/bash
      【解决方案6】:

      我建议你使用 Xdialog、Kdialog 或 zenity 以及它的进度选项。

      【讨论】:

      • 忘了说,(不确定是否相关),在只有 SSH,没有 GUI 的 Ubuntu 10.04 机器上。这些似乎是针对带有 GUI 的,但是我想由于它是 unix 的,所以无论如何它都适用于 SSH。
      • OK,那么pv就是最优解。
      猜你喜欢
      • 2012-12-22
      • 2018-04-06
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      • 2011-08-11
      相关资源
      最近更新 更多