使用BASH显示进度(工作)指示器

Pez*_*kow 52 unix bash shell progress

使用仅限bash脚本,如何提供bash进度指示器?

所以我可以运行命令表单bash,并且在执行该命令时让用户知道某些事情仍在发生.

Pez*_*kow 69

在这个使用SCP的例子中,我正在演示如何获取进程id(pid),然后在该进程运行时执行某些操作.

这会显示一个简单的spinnng图标.

/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
Run Code Online (Sandbox Code Playgroud)

William Pursell的解决方案

/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
Run Code Online (Sandbox Code Playgroud)

  • 它更简单:`s =' - \| /'; I = 0; 而kill -0 $ pid; 我= $(((i + 1)%4)); printf"\ r $ {s:$ i:1}"; 睡觉.1; done` (4认同)
  • `while [kill -0 $ pid]`会导致`第102行:[: - 0:二元运算符预期'错误.我必须使用`while kill -0 $ pid;`而不是! (3认同)
  • +1 这真的很好:其他解决方案使用的 LOC 的三分之一。 (2认同)
  • 您需要在后台运行`scp`,或者在此脚本的其余部分运行之前完成.(`$!`也需要背景才有意义). (2认同)

evi*_*tto 24

如果您有办法估算完成的百分比,例如当前处理的文件数和总数,您可以制作一个简单的线性进度表,其中包含一些关于屏幕宽度的数学和假设.

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
Run Code Online (Sandbox Code Playgroud)

或者您可以估算剩余时间而不是线性仪表.它和其他类似的东西一样准确.

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"
Run Code Online (Sandbox Code Playgroud)


che*_*sum 19

这里推荐的是一个很好的微调器功能(稍加修改),也可以帮助你的光标保持在原来的位置.

spinner()
{
    local pid=$!
    local delay=0.75
    local spinstr='|/-\'
    while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
        local temp=${spinstr#?}
        printf " [%c]  " "$spinstr"
        local spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b\b\b\b"
    done
    printf "    \b\b\b\b"
}
Run Code Online (Sandbox Code Playgroud)

用法:

(a_long_running_task) &
spinner
Run Code Online (Sandbox Code Playgroud)


cos*_*r11 12

这是一个非常简单的技术:(
只需替换sleep 20为您要指示正在运行的任何命令)

#!/bin/bash

sleep 20 & PID=$! #simulate a long process

echo "THIS MAY TAKE A WHILE, PLEASE BE PATIENT WHILE ______ IS RUNNING..."
printf "["
# While process is running...
while kill -0 $PID 2> /dev/null; do 
    printf  "?"
    sleep 1
done
printf "] done!"
Run Code Online (Sandbox Code Playgroud)

输出如下所示:

> THIS MAY TAKE A WHILE, PLEASE BE PATIENT WHILE ______ IS RUNNING...
> [????????????????????????] done!
Run Code Online (Sandbox Code Playgroud)

?每秒增加一个(高密度点缀),直到过程完成.

  • 你如何在函数中使用它? (2认同)
  • 您可以开始该过程,获取PID,然后将其传递到包含“ echo”和“ done!”之间的代码的函数中。 (2认同)

小智 7

这是一个简单的在线人,我使用:

while true; do for X in '-' '/' '|' '\'; do echo -en "\b$X"; sleep 0.1; done; done 
Run Code Online (Sandbox Code Playgroud)


f1l*_*t3r 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
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到源:https : //gist.github.com/F1LT3R/fa7f102b08a514f2c535


Vic*_*art 5

这是一个“活动指示器”示例,用于通过 linux 'speedtest-cli' 命令进行互联网连接速度测试:

printf '\n\tInternet speed test:  '

# http://stackoverflow.com/questions/12498304/using-bash-to-display-a-progress-working-indicator

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

# http://stackoverflow.com/questions/20165057/executing-bash-loop-while-command-is-running

speedtest > .st.txt &           ## & : continue running script
pid=$!                          ## PID of last command

# If this script is killed, kill 'speedtest':
trap "kill $pid 2> /dev/null" EXIT

# While 'speedtest' is running:
while kill -0 $pid 2> /dev/null; do
for i in "${spin[@]}"
do
    echo -ne "\b$i"
    sleep 0.1
done
done

# Disable the trap on a normal exit:
trap - EXIT

printf "\n\t           "
grep Download: .st.txt
printf "\t             "
grep Upload: .st.txt
echo ''
rm -f st.txt
Run Code Online (Sandbox Code Playgroud)

更新 - 示例:

动画 GIF


nac*_*ker 5

除了经典的微调器,您还可以使用此进度条

通过使用半块字符来实现子字符精度

在此处输入图片说明

链接中包含的代码。