没有对话框或光伏的bash脚本的进度指示器

时间:2015-11-02 19:35:58

标签: bash

我编写了一个bash脚本来截断服务器列表并执行各种命令。我希望在脚本运行时合并一个完成百分比的进度指示器。我在网上发现了一个脚本来执行此操作,但它无法正常工作,我不确定如何使用它。

此处对话框命令不是一个选项,因为我正在使用nsh

#!/bin/bash

i=0
while [[ $i -lt 11 ]]; do
##
##  \r = carriage return
##  \c = suppress linefeed
##
echo -en "\r$i%\c\b"
(( i=i+1 ))
sleep 1
done

echo

exit 0

出于测试目的,我只连接到每个服务器并回显主机名。

for i in $(cat serverlist.txt)
do
nexec -i hostname
done

如何在浏览上述代码中的服务器列表时利用剪切的第一个代码来显示进度?

2 个答案:

答案 0 :(得分:1)

要跟踪您的进度,您需要将服务器列表存储在一个数组中,以便知道有多少服务器:

mapfile -t servers <serverlist.txt    # servers is an array
n=${#servers[@]}                      # how many

i=0
for server in "${servers[@]}"; do
    ((i++))
    progress=$(( i * 100 / n )) 
    nexec ...
    echo "you are ${progress}% complete"
done

答案 1 :(得分:0)

write_status() {
  done=0
  total=$1
  columns=${COLUMNS:-100}

  # print initial, empty progress bar
  for (( i=0; i<columns; i++ )); do printf '-'; done; printf '\r'

  # every time we read a line, print a progress bar with one more item complete
  while read -r; do
    done=$(( done + 1 ))
    pct=$(( done * columns / total ))
    for ((i=0; i<pct; i++)); do
      printf '+'
    done
    for ((i=pct; i<columns; i++)); do
      printf '-'
    done
    printf '\r'
    if (( done == total )); then break; fi
  done 
}

# read server names into an array; the below is bash 4.x syntax
readarray -t servers <serverlist.txt

# direct FD 4 to the a subshell running the write_status function
exec 4> >(write_status "${#servers[@]}")

for hostname in "${servers[@]}"; do
  nexec -i "$hostname"  # actually run the command
  echo >&4              # ...and notify write_status that it completed
done

如果要并行化远程命令,可以通过使用以下内容替换底部的for循环来实现:

for hostname in "${servers[@]}"; do
  (nexec -i "$hostname"; echo >&4) &
done
wait

如果您的shell是4.0之前的bash版本,那么readarray -t servers <serverlist可以替换为以下内容:

servers=( )
while IFS= read -r server; do servers+=( "$server" ); done <serverlist.txt