Bash 进度条

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11592583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:50:20  来源:igfitidea点击:

Bash progress bar

bashprogress-bar

提问by Zippyduda

I'm using the following script to go through a large list of domains in whois and find the registrar (useful for server/DNS migrations) and it works fine.

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

However I am wanting to incorporate a progress bar into it just for the sake of convenience. Here's my script, if it can be improved let me know:

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

#!/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."

I've tried this first: http://moblog.bradleyit.com/2010/02/simple-bash-progress-bar-function.html

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

And then thisbut with no luck.

然后这个,但没有运气。

What do you reckon is the easiest way to get a progress bar implemented into that script?

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

回答by Ian Brown

Here's a fancy progress bar that you might enjoy...

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

#!/bin/bash
#   Slick Progress Bar
#   Created by: Ian Brown ([email protected])
#   Please share with me your modifications
# Functions
PUT(){ echo -en "3[;H";}  
DRAW(){ echo -en "3%";echo -en "3(0";}         
WRITE(){ echo -en "3(B";}  
HIDECURSOR(){ echo -en "3[?25l";} 
NORM(){ echo -en "3[?12l3[?25h";}
function showBar {
        percDone=$(echo 'scale=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 "3[7m 3[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

looks like this:

看起来像这样:

looks like this

看起来像这样

回答by nshy

You can use pvbut the other way.

你可以用pv另一种方式。

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

so you use echo Xto say when another portion of work is done and this is counted by pv, it's know what the whole job size is due to -soption.

所以你常echo X说当另一部分工作完成时,这是由 pv 计算的,它知道整个工作的大小是由于-s选项。

回答by ivanalejandro0

You could use something like:

你可以使用类似的东西:

progress(){
    # example usage:
    # progress 30G 9G 30
    # 30G [================>.................................] 30% (9G)

    # params:
    #  = total value (e.g.: source size)
    #  = current value (e.g.: destination size)
    #  = percent completed
    [[ -z  || -z  || -z  ]] && exit  # on empty param...

    percent=
    completed=$(( $percent / 2 ))
    remaining=$(( 50 - $completed ))

    echo -ne "\r ["
    printf "%0.s=" `seq $completed`
    echo -n ">"
    [[ $remaining != 0 ]] && printf "%0.s." `seq $remaining`
    echo -n "] $percent% ()  "
}

from https://gist.github.com/ivanalejandro0/9159989

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

You can see an usage example in https://github.com/ivanalejandro0/misc/blob/master/shell-scripts/copy-progress.sh

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

回答by Dunes

Change the outer loop to:

将外循环更改为:

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

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

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

Or you can use any other program that provides a progress bar based on how much a file has been read.

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

回答by geirha

Given that you mentioned in a comment that you're on a debian based system, you could use whiptail. When you install a deb package that requires configuration, text-based windows are drawn to ask you stuff; that's whiptail.

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

Something like

就像是

#!/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

回答by igustin

I suggest you to use Xdialog, Kdialog or zenity and it's progress option.

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