如何在Shell脚本中添加进度条?

543

在bash或其他* NIX中运行脚本时,如果要运行的命令需要花费几秒钟以上的时间,则需要使用进度条。

例如,拷贝大文件,打开大的tar文件等。

您推荐使用哪些方法来为shell脚本添加进度条?


请参考https://dev59.com/7Wcs5IYBdhLWcg3w5H5a,了解控制逻辑的示例(将作业放入后台并执行某些操作,直到其完成)。 - tripleee
4
在脚本编写时,我们经常需要一些要求:记录日志、显示进度、着色、特殊输出等等。我一直觉得应该有一种简单的脚本框架,但找不到,所以我决定自己实现一个。你可能会觉得这很有用。它纯粹使用 Bash 编写,就是说只用 Bash。https://github.com/SumuduLansakara/JustBash - Anubis
这个问题不应该移至 unix.stackexchange.com 吗? - Ethan
我喜欢在任何可以使用管道的情况下使用 pv。例如:ssh remote "cd /home/user/ && tar czf - accounts" | pv -s 23091k | tar xz - bitsoflogic
42个回答

-3

我曾经也有一个繁忙的脚本,几个小时都没有任何进展。所以我实现了一个函数,主要包括之前答案中提到的技巧:

#!/bin/bash
# Updates the progress bar
# Parameters: 1. Percentage value
update_progress_bar()
{
  if [ $# -eq 1 ];
  then
    if [[ $1 == [0-9]* ]];
    then
      if [ $1 -ge 0 ];
      then
        if [ $1 -le 100 ];
        then
          local val=$1
          local max=100

          echo -n "["

          for j in $(seq $max);
          do
            if [ $j -lt $val ];
            then
              echo -n "="
            else
              if [ $j -eq $max ];
              then
                echo -n "]"
              else
                echo -n "."
              fi
            fi
          done

          echo -ne " "$val"%\r"

          if [ $val -eq $max ];
          then
            echo ""
          fi
        fi
      fi
    fi
  fi
}

update_progress_bar 0
# Further (time intensive) actions and progress bar updates
update_progress_bar 100

1
你可以将前面的四个if语句合并成一个if语句,并使用一系列AND运算符,因为它们中没有任何特定的代码: if [ $# -eq 1 ] && [[ $1 == [0-9]* ]] && [ $1 -ge 0 ] && [ $1 -le 100 ];你还可以通过printf和命令替换来避免for循环并缩短代码: printf "["; printf "%.0=" $(seq $val); printf "%.0." $(seq $[ $val+1 ] $max); printf "] %s%%\r" $val; - CaffeineConnoisseur

-5

今天我也有同样的事情要做,根据Diomidis的回答,这是我所做的(Linux Debian 6.0.7)。也许这能帮到你:

#!/bin/bash

echo "getting script inode"
inode=`ls -i ./script.sh | cut -d" " -f1`
echo $inode

echo "getting the script size"
size=`cat script.sh | wc -c`
echo $size

echo "executing script"
./script.sh &
pid=$!
echo "child pid = $pid"

while true; do
        let offset=`lsof -o0 -o -p $pid | grep $inode | awk -F" " '{print $7}' | cut -d"t" -f 2`
        let percent=100*$offset/$size
        echo -ne " $percent %\r"
done

你能解释一下偏移量计算是什么吗? - deven98602
当我以root身份启动此脚本时,我会收到以下错误提示:lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /home/rubo77/.gvfs Output information may be incomplete. - rubo77
当我在Ubuntu 13.04上使用progressbar.sh脚本并通过cd / tmp /; echo“sleep 5”> script.sh; bash progressbar.sh调用时,我会收到错误消息:“progressbar:Zeile 17: let: offset =:Syntax Fehler:Operator erwartet。 (Fehlerverursachendes Zeichen是“=”)。” - rubo77

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接