Gha*_*eed 14 command-line bash
如何使用 bash 创建进度条?
这是我的脚本:
#!/bin/bash
pass='number1 number12 number13 number14 number15 number16'
chk='number14'
for i in $pass ; do
if [ "$i" == "$chk" ]; then
echo ' Found ^_^'
else
echo 'loading 50%'
fi
done
Run Code Online (Sandbox Code Playgroud)
我想echo 'loading 50%'用任何东西替换来创建一个进度条。
Mik*_*kel 14
whiptail 预装在 Ubuntu 和许多其他发行版上,并将显示全屏(但仍然基于终端)进度元素。
dialog是 的超集whiptail,所以这个例子对两者同样适用。它确实提供了更高级的 UI 元素,因此如果您正在寻找诸如文件选择器和表单之类的用户交互,它可能会派上用场,但它的缺点是没有预装在许多系统上。
for i in $(seq 1 100)
do
sleep 0.1
echo $i
done | whiptail --title 'Test script' --gauge 'Running...' 6 60 0
Run Code Online (Sandbox Code Playgroud)
请注意,脚本输出被解释为百分比,因此您可能需要相应地调整输出。
Whiptail 和 Dialog 还允许您在运行时通过相当神秘的语法修改文本:
phases=(
'Locating Jebediah Kerman...'
'Motivating Kerbals...'
'Treating Kessler Syndrome...'
'Recruiting Kerbals...'
)
for i in $(seq 1 100); do
sleep 0.1
if [ $i -eq 100 ]; then
echo -e "XXX\n100\nDone!\nXXX"
elif [ $(($i % 25)) -eq 0 ]; then
let "phase = $i / 25"
echo -e "XXX\n$i\n${phases[phase]}\nXXX"
else
echo $i
fi
done | whiptail --title 'Kerbal Space Program' --gauge "${phases[0]}" 6 60 0
Run Code Online (Sandbox Code Playgroud)
pv显示通过管道传输的文件或流的进度。然而,它不能(很容易?)用于显示自定义操作(例如循环)的进度。它专为流而设计。
$ head -c 1G < /dev/urandom | pv -s 1G > /dev/null
277MB 0:00:16 [17.4MB/s] [========> ] 27% ETA 0:00:43
Run Code Online (Sandbox Code Playgroud)
一些pv可以派上用场的真实示例:
# progress while importing a DB dump
pv mybigfile.sql | mysql -uroot -p dbname
# importing straight from a remote server
ssh user@server 'cat mybigfile.sql.gz' | pv | gzip -cd | mysql -uroot -p dbname
# taking a snapshot of a btrfs partition
btrfs send /snapshots/$date | pv | btrfs receive /mnt/backup/root
Run Code Online (Sandbox Code Playgroud)
我不知道有任何命令可以提供pv或样式的单行进度条wget,但是有很多简单的 Bash/Perl/sed 脚本可以添加该功能,正如其他人在此处共享的那样。
您可以使用zenity创建简单的 GTK 对话窗口。可用选项之一是进度条对话框。
您可以使用zenity --progress. 为了使它有用,您应该通过添加以下一些选项来指定更多信息(摘自man zenity):
Progress options
--text=STRING
Set the dialog text
--percentage=INT
Set initial percentage
--auto-close
Close dialog when 100% has been reached
--auto-kill
Kill parent process if cancel button is pressed
--pulsate
Pulsate progress bar
--no-cancel
Hides the cancel button
Run Code Online (Sandbox Code Playgroud)
有两种模式:
pulsating : 进度条是脉动的,它只是表示有什么东西在运行,但并没有说明任何关于进度的信息。您可以通过设置--pulsating选项来做到这一点。
手动:您必须将当前进度百分比通过管道传输到zenity命令的标准输入以更新进度条。
一个例子可能如下所示。请注意,前面的命令被分组到一个子shell,以便所有输出都重定向到zenity对话框,而不仅仅是最后一个命令的输出:
(echo 10; sleep 2; echo 20; sleep 2; echo 50; sleep 2) | zenity --progress
Run Code Online (Sandbox Code Playgroud)这段代码会做到这一点,并且不需要任何东西(当然除了 bash)。它会打印#标志,就像您在评论中所问的那样:
pass='number1 number12 number13 number14 number15 number16'
chk='number14'
passarr=($pass)
lenProgressBar=${#passarr[@]}
echo -n '['
i=0
while [ $i -lt $lenProgressBar ]; do
echo -n '-'
((i++))
done
echo -n ']'
i=0
while [ $i -lt $lenProgressBar ]; do
echo -e -n '\b'
((i++))
done
echo -e -n '\b'
for i in $pass ; do
if [ "$i" = "$chk" ]; then
echo -e '#\nFound ^_^'
break
else
echo -n '#'
fi
done
Run Code Online (Sandbox Code Playgroud)
但是,如果您有很多事情要检查,这只会让您的屏幕充满#标志。要解决该问题,请尝试以下代码:
lenProgressBar=5
pass='number1 number12 number13 number14 number15 number16'
chk='number14'
passarr=($pass)
lenPass=${#passarr[@]}
if [ $lenProgressBar -gt $lenPass ]; then
lenProgressBar=lenPass
elif [ $lenProgressBar -lt 1 ]; then
lenProgressBar=1
fi
let "chksForEqualsPrint = $lenPass / $lenProgressBar"
echo -n '['
i=0
while [ $i -lt $lenProgressBar ]; do
echo -n '-'
((i++))
done
echo -n ']'
i=0
while [ $i -lt $lenProgressBar ]; do
echo -e -n '\b'
((i++))
done
echo -e -n '\b'
n=1
for i in $pass ; do
if [ "$i" = "$chk" ]; then
echo -e '\nFound ^_^'
break
else
if [ $n -eq $chksForEqualsPrint ]; then
echo -n '#'
n=1
else
((n++))
fi
fi
done
Run Code Online (Sandbox Code Playgroud)
将第一行 ( lenProgressBar=5) 中的 5 更改为您希望进度条的长度。打印#长度较短的进度条比长度较长的标志需要更长的时间,但不要让进度条的长度超过您的屏幕尺寸;如果你这样做,它不会很好地工作。(它不会让您使用高于您正在检查的项目数或低于 1 的项目数的进度条)