当在bash或*NIX中的任何其他shell中编写脚本时,在运行需要超过几秒钟时间的命令时,需要一个进度条。
例如,复制一个大文件,打开一个大tar文件。
你建议用什么方法向shell脚本添加进度条?
当在bash或*NIX中的任何其他shell中编写脚本时,在运行需要超过几秒钟时间的命令时,需要一个进度条。
例如,复制一个大文件,打开一个大tar文件。
你建议用什么方法向shell脚本添加进度条?
当前回答
一些帖子已经展示了如何显示命令的进度。为了计算它,你需要看看你已经进步了多少。在BSD系统上,一些命令,如dd(1),接受SIGINFO信号,并报告它们的进程。在Linux系统上,一些命令的响应类似于SIGUSR1。如果这个工具可用,您可以通过dd管道输入以监视处理的字节数。
或者,您可以使用lsof来获取文件读指针的偏移量,从而计算进度。我编写了一个名为pmonitor的命令,用于显示处理指定进程或文件的进度。有了它,你可以做以下事情。
$ pmonitor -c gzip
/home/dds/data/mysql-2015-04-01.sql.gz 58.06%
Linux和FreeBSD shell脚本的早期版本出现在我的博客上(“在Unix上监视进程进度”)。
其他回答
#!/bin/bash
function progress_bar() {
bar=""
total=10
[[ -z $1 ]] && input=0 || input=${1}
x="##"
for i in `seq 1 10`; do
if [ $i -le $input ] ;then
bar=$bar$x
else
bar="$bar "
fi
done
#pct=$((200*$input/$total % 2 + 100*$input/$total))
pct=$(($input*10))
echo -ne "Progress : [ ${bar} ] (${pct}%) \r"
sleep 1
if [ $input -eq 10 ] ;then
echo -ne '\n'
fi
}
可以创建一个函数,以1-10的比例绘制bar数:
progress_bar 1
echo "doing something ..."
progress_bar 2
echo "doing something ..."
progress_bar 3
echo "doing something ..."
progress_bar 8
echo "doing something ..."
progress_bar 10
我想根据命令输出的行数和之前运行的目标行数来跟踪进度:
#!/bin/bash
function lines {
local file=$1
local default=$2
if [[ -f $file ]]; then
wc -l $file | awk '{print $1}';
else
echo $default
fi
}
function bar {
local items=$1
local total=$2
local size=$3
percent=$(($items*$size/$total % $size))
left=$(($size-$percent))
chars=$(local s=$(printf "%${percent}s"); echo "${s// /=}")
echo -ne "[$chars>";
printf "%${left}s"
echo -ne ']\r'
}
function clearbar {
local size=$1
printf " %${size}s "
echo -ne "\r"
}
function progress {
local pid=$1
local total=$2
local file=$3
bar 0 100 50
while [[ "$(ps a | awk '{print $1}' | grep $pid)" ]]; do
bar $(lines $file 0) $total 50
sleep 1
done
clearbar 50
wait $pid
return $?
}
然后这样使用它:
target=$(lines build.log 1000)
(mvn clean install > build.log 2>&1) &
progress $! $target build.log
它输出一个进度条,看起来像这样:
[===============================================> ]
条形图随着输出行数达到目标而增长。如果行数超过了目标,条就重新开始(希望目标是好的)。
BTW:我在Mac OSX上使用bash。我基于这个代码从mariascio旋转。
我需要一个进度条,将适合弹出气泡消息(通知-发送),以代表电视音量水平。最近我一直在用python写一个音乐播放器,而电视画面大部分时间都是关闭的。
终端输出样本
Bash脚本
#!/bin/bash
# Show a progress bar at step number $1 (from 0 to 100)
function is_int() { test "$@" -eq "$@" 2> /dev/null; }
# Parameter 1 must be integer
if ! is_int "$1" ; then
echo "Not an integer: ${1}"
exit 1
fi
# Parameter 1 must be >= 0 and <= 100
if [ "$1" -ge 0 ] && [ "$1" -le 100 ] 2>/dev/null
then
:
else
echo bad volume: ${1}
exit 1
fi
# Main function designed for quickly copying to another program
Main () {
Bar="" # Progress Bar / Volume level
Len=25 # Length of Progress Bar / Volume level
Div=4 # Divisor into Volume for # of blocks
Fill="▒" # Fill up to $Len
Arr=( "▉" "▎" "▌" "▊" ) # UTF-8 left blocks: 7/8, 1/4, 1/2, 3/4
FullBlock=$((${1} / Div)) # Number of full blocks
PartBlock=$((${1} % Div)) # Size of partial block (array index)
while [[ $FullBlock -gt 0 ]]; do
Bar="$Bar${Arr[0]}" # Add 1 full block into Progress Bar
(( FullBlock-- )) # Decrement full blocks counter
done
# If remainder zero no partial block, else append character from array
if [[ $PartBlock -gt 0 ]]; then
Bar="$Bar${Arr[$PartBlock]}"
fi
while [[ "${#Bar}" -lt "$Len" ]]; do
Bar="$Bar$Fill" # Pad Progress Bar with fill character
done
echo Volume: "$1 $Bar"
exit 0 # Remove this line when copying into program
} # Main
Main "$@"
测试bash脚本
使用此脚本测试终端中的进度条。
#!/bin/bash
# test_progress_bar3
Main () {
tput civis # Turn off cursor
for ((i=0; i<=100; i++)); do
CurrLevel=$(./progress_bar3 "$i") # Generate progress bar 0 to 100
echo -ne "$CurrLevel"\\r # Reprint overtop same line
sleep .04
done
echo -e \\n # Advance line to keep last progress
echo "$0 Done"
tput cnorm # Turn cursor back on
} # Main
Main "$@"
博士TL;
本节详细介绍如何使用notify-send将弹出气泡消息快速发送到桌面。这是必需的,因为音量级别可以在一秒钟内更改多次,并且默认的气泡消息行为是让消息在桌面上停留许多秒。
示例弹出气泡消息
弹出气泡消息bash代码
从上面的脚本中,主函数被复制到一个名为tvpowered的现有bash脚本中名为VolumeBar的新函数。已删除复制的主函数中的exit 0命令。
下面是如何调用它并让Ubuntu的notify-send命令知道我们将发送弹出泡泡消息:
VolumeBar $CurrVolume
# Ask Ubuntu: https://askubuntu.com/a/871207/307523
notify-send --urgency=critical "tvpowered" \
-h string:x-canonical-private-synchronous:volume \
--icon=/usr/share/icons/gnome/48x48/devices/audio-speakers.png \
"Volume: $CurrVolume $Bar"
这是一个新的行,它告诉notify-send立即替换上一个弹出气泡:
-h string:x-canonical-private-synchronous:volume \
卷将弹出气泡消息分组在一起,该组中的新消息立即替换前一个消息。你可以用任何东西来代替体积。
要指示活动的进度,请尝试以下命令:
while true; do sleep 0.25 && echo -ne "\r\\" && sleep 0.25 && echo -ne "\r|" && sleep 0.25 && echo -ne "\r/" && sleep 0.25 && echo -ne "\r-"; done;
OR
while true; do sleep 0.25 && echo -ne "\rActivity: \\" && sleep 0.25 && echo -ne "\rActivity: |" && sleep 0.25 && echo -ne "\rActivity: /" && sleep 0.25 && echo -ne "\rActivity: -"; done;
OR
while true; do sleep 0.25 && echo -ne "\r" && sleep 0.25 && echo -ne "\r>" && sleep 0.25 && echo -ne "\r>>" && sleep 0.25 && echo -ne "\r>>>"; sleep 0.25 && echo -ne "\r>>>>"; done;
OR
while true; do sleep .25 && echo -ne "\r:Active:" && sleep .25 && echo -ne "\r:aCtive:" && sleep .25 && echo -ne "\r:acTive:" && sleep .25 && echo -ne "\r:actIve:" && sleep .25 && echo -ne "\r:actiVe:" && sleep .25 && echo -ne "\r:activE:"; done;
可以在while循环中使用标志/变量来检查和显示进度的值/范围。
https://github.com/extensionsapp/progre.sh
创造40%的进度:progress 40