71

bash のみのスクリプトを使用して、bash の進行状況インジケーターをどのように提供できますか?

たとえば、bash からコマンドを実行すると、そのコマンドの実行中に、まだ何かが起こっていることをユーザーに知らせます。

4

12 に答える 12

88

SCP を使用したこの例では、プロセス ID (pid) を取得し、そのプロセスの実行中に何かを実行する方法を示しています。

これにより、単純な回転アイコンが表示されます。

/usr/bin/scp me@website.com:file somewhere 2>/dev/null &
pid=$! # Process Id of the previous running command

spin[0]="-"
spin[1]="\\"
spin[2]="|"
spin[3]="/"

echo -n "[copying] ${spin[0]}"
while [ kill -0 $pid ]
do
  for i in "${spin[@]}"
  do
        echo -ne "\b$i"
        sleep 0.1
  done
done

ウィリアム・パーセルのソリューション

/usr/bin/scp me@website.com:file somewhere 2>/dev/null &
pid=$! # Process Id of the previous running command

spin='-\|/'

i=0
while kill -0 $pid 2>/dev/null
do
  i=$(( (i+1) %4 ))
  printf "\r${spin:$i:1}"
  sleep .1
done
于 2012-09-19T15:50:18.277 に答える
28

現在処理されているファイル数や合計数など、完了したパーセンテージを推定する方法がある場合は、簡単な計算と画面幅に関する仮定を使用して、単純な線形進行状況メーターを作成できます。

count=0
total=34
pstr="[=======================================================================]"

while [ $count -lt $total ]; do
  sleep 0.5 # this is work
  count=$(( $count + 1 ))
  pd=$(( $count * 73 / $total ))
  printf "\r%3d.%1d%% %.${pd}s" $(( $count * 100 / $total )) $(( ($count * 1000 / $total) % 10 )) $pstr
done

または、リニア メーターの代わりに、残り時間を推定することもできます。他の同様のものと同じくらい正確です。

count=0
total=34
start=`date +%s`

while [ $count -lt $total ]; do
  sleep 0.5 # this is work
  cur=`date +%s`
  count=$(( $count + 1 ))
  pd=$(( $count * 73 / $total ))
  runtime=$(( $cur-$start ))
  estremain=$(( ($runtime * $total / $count)-$runtime ))
  printf "\r%d.%d%% complete ($count of $total) - est %d:%0.2d remaining\e[K" $(( $count*100/$total )) $(( ($count*1000/$total)%10)) $(( $estremain/60 )) $(( $estremain%60 ))
done
printf "\ndone\n"
于 2012-09-19T18:42:53.723 に答える
19
于 2016-04-11T00:59:42.477 に答える
9

ここで、私が使用する簡単なワンライナーを示します。

while true; do for X in '-' '/' '|' '\'; do echo -en "\b$X"; sleep 0.1; done; done 
于 2015-12-21T09:23:24.017 に答える
6

これが私の試みです。私はスクリプトをbashするのが初めてなので、このコードのいくつかはひどいかもしれません:)

出力例:

進行中 終わり

コード:

progressBarWidth=20

# Function to draw progress bar
progressBar () {

  # Calculate number of fill/empty slots in the bar
  progress=$(echo "$progressBarWidth/$taskCount*$tasksDone" | bc -l)  
  fill=$(printf "%.0f\n" $progress)
  if [ $fill -gt $progressBarWidth ]; then
    fill=$progressBarWidth
  fi
  empty=$(($fill-$progressBarWidth))

  # Percentage Calculation
  percent=$(echo "100/$taskCount*$tasksDone" | bc -l)
  percent=$(printf "%0.2f\n" $percent)
  if [ $(echo "$percent>100" | bc) -gt 0 ]; then
    percent="100.00"
  fi

  # Output to screen
  printf "\r["
  printf "%${fill}s" '' | tr ' ' ▉
  printf "%${empty}s" '' | tr ' ' ░
  printf "] $percent%% - $text "
}



## Collect task count
taskCount=33
tasksDone=0

while [ $tasksDone -le $taskCount ]; do

  # Do your task
  (( tasksDone += 1 ))

  # Add some friendly output
  text=$(echo "somefile-$tasksDone.dat")

  # Draw the progress bar
  progressBar $taskCount $taskDone $text

  sleep 0.01
done

echo

ここでソースを見ることができます: https://gist.github.com/F1LT3R/fa7f102b08a514f2c535

于 2016-01-22T16:10:29.690 に答える
0

bash スクリプト用のサイケデリック プログレス バー。コマンド ラインで './progressbar x y' として呼び出します。ここで、'x' は秒単位の時間、'y' は表示するメッセージです。内部関数の progressbar() はスタンドアロンでも機能し、'x' をパーセンテージとして、'y' をメッセージとして受け取ります。

#!/bin/bash

if [ "$#" -eq 0 ]; then echo "x is \"time in seconds\" and z is \"message\""; echo "Usage: progressbar x z"; exit; fi
progressbar() {
        local loca=$1; local loca2=$2;
        declare -a bgcolors; declare -a fgcolors;
        for i in {40..46} {100..106}; do
                bgcolors+=("$i")
        done
        for i in {30..36} {90..96}; do
                fgcolors+=("$i")
        done
        local u=$(( 50 - loca ));
        local y; local t;
        local z; z=$(printf '%*s' "$u");
        local w=$(( loca * 2 ));
        local bouncer=".oO°Oo.";
        for ((i=0;i<loca;i++)); do
                t="${bouncer:((i%${#bouncer})):1}"
                bgcolor="\\E[${bgcolors[RANDOM % 14]}m \\033[m"
                y+="$bgcolor";
        done
        fgcolor="\\E[${fgcolors[RANDOM % 14]}m"
        echo -ne " $fgcolor$t$y$z$fgcolor$t \\E[96m(\\E[36m$w%\\E[96m)\\E[92m $fgcolor$loca2\\033[m\r"
};
timeprogress() {
        local loca="$1"; local loca2="$2";
        loca=$(bc -l <<< scale=2\;"$loca/50")
        for i in {1..50}; do
                progressbar "$i" "$loca2";
                sleep "$loca";
        done
        echo -e "\n"
};
timeprogress "$1" "$2"
于 2016-05-19T21:18:27.160 に答える