如果你有在dialog
实用工具安装的(),您可以轻松地做出一个漂亮的滚动显示:
find . -type f -name glob -exec echo {} \; -exec cmd {} \; |
dialog --progressbox "Files being processed..." 12 $((COLUMNS*3/2))
参数--progressbox
是框的标题(可选,不能看起来像一个数字);文本行中的高度和文本列中的宽度。 dialog
有一堆选项来自定义演示文稿;以上只是为了让你开始。
dialog
也有一个进度条,也称为“计量器”,但正如@ glennjackman在他的回答中指出的那样,您需要知道为了显示进度需要做多少工作。一种方法是收集find命令的整个输出,计算其中的文件数量,然后从累计输出中运行所需的任务。但是,这意味着要等到find命令完成才能开始工作,这可能不合意。
仅仅因为这是一个有趣的挑战,我提出了以下解决方案,这可能是过度设计的,因为它试图解决所有我能想到的外壳问题(甚至如此,它可能会错过一些) 。它由两个壳文件:
# File: run.sh
#!/bin/bash
# Usage: run.sh root-directory find-tests
#
# Fix the following path as required
PROCESS="$HOME/bin/process.sh"
TD=$(mktemp --tmpdir -d gauge.XXXXXXXX)
find "[email protected]" -print0 |
tee >(awk -vRS='\0' 'END{print NR > "'"$TD/_total"'"}';
ln -s "$TD/_total" "$TD/total") |
{ xargs -0 -n50 "$PROCESS" "$TD"; printf "XXX\n100\nDone\nXXX\n"; } |
dialog --gauge "Starting..." 7 70
rm -fR "$TD"
# File: process.sh
#!/bin/bash
TD="$1"; shift
TOTAL=
if [[ -f $TD/count ]]; then COUNT=$(cat "$TD/count"); else COUNT=0; fi
for file in "[email protected]"; do
if [[ -z $TOTAL && -f $TD/total ]]; then TOTAL=$(cat "$TD/total"); fi
printf "XXX\n%d\nProcessing file\n%q\nXXX\n" \
$((COUNT*100/${TOTAL:-100})) "$file"
#
# do whatever you want to do with $file
#
((++COUNT))
done
echo $COUNT > "$TD/count"
一些注意事项:
有很多散落在上述GNU扩展。我没有列出完整的列表,但它肯定包含%q
printf格式(可能只是%s
);用于NUL终止文件名列表的标志和mktemp
的--tmpdir
标志。
run.sh
使用tee
来同时计算找到的文件数(使用awk
)并开始处理文件。
-n50
参数xargs
导致它只会等待前50个文件,以避免在找到第一个文件时花费大量时间来延迟启动;它可能没有必要。
的-vRS='\0'
参数awk
导致它使用一个NUL
作为行定界符,以匹配-print0
行动find
(以及-0
选项xargs
);所有这些仅在文件路径可能包含新行时才是必需的。
awk
写入计数_total
,然后我们的符号链接_total
到total
,以避免它完全写入之前在那里total
读一个非常不可能的竞争条件。符号链接是原子的,所以这样做可以保证total
要么不存在,要么完全写入。
对文件的总大小进行计数而不是对其进行计数可能会更好,尤其是在处理工作与文件大小(例如压缩)相关的情况下。这将是一个相当简单的修改。此外,使用并行执行功能也很诱人,但这需要更多的工作来协调并行进程之间处理文件的总和。
如果您使用的托管环境没有dialog
,最简单的解决方案是仅使用ssh
从具有dialog
的环境运行上述脚本。从run.sh删除| dialog --gauge "Starting..." 7 70
,并把它放在你的ssh
调用来代替:ssh [email protected] /path/to/run.sh root-dir find-tests | dialog --gauge "Starting..." 7 70
对,你有没有想法如何确定数字任务,“Y”,没有显着增加运行时?不幸的是,'code'find'code'需要很长的时间才能枚举文件。'du'命令可能会起作用吗?我会在更多的研究后更新。现在,这对我来说似乎是一个很好的解决方法。我会让你知道它是怎么回事。 – Bts
这似乎是打印每个文件进行操作的进度指示器。无论如何要把它扩展到整个查找命令?换句话说,可以通过某种方式更改此代码,以便不会为找到的每个文件都打印新的微调器,而是为了查找的整个操作? – Bts