问题
I have a simple Unix shell script which is executing a time-consuming find
command. Till it executes, my script appears non-responsive. However it's actually running in reality.
How can I add a progress bar or print dots till the find
command is executing?
I want to print some dots or hash till the function doSomething
is executing.
function doSomething()
{
# Time-consuming 'for' loop below
for var in `find XXXXXX`
do
# Some more processing
done;
}
# Call the function doSomething. Need the progress DOTS till doSomething is executing
doSomething
# Remaining script processing
I have tried to google, but none of the solutions fits what I am trying to achieve. Any suggestions?
回答1:
As suggested in the comments, how about a simple spinner? It is easy enough to knock something up in awk
, which copies input to standard output and prints a spinner to standard error:
$ cat spinner.awk
{ printf "%s\r", substr("|/-\\", NR % 4 + 1, 1) > "/dev/stderr" }
1
which you can then pipe find
through.
for var in `find XXXXXX | awk -f spinner.awk`
do
#some more processing
done;
回答2:
You can run a spinner in the background
#!/usr/bin/env bash
spinner() {
local s="|/-\\"
local -i i=0
while :; do
printf "%s\\r" "${s:$((i++%4)):1}" >&2
sleep .05
done
}
function doSomething()
{
# time consuming for loop below
# See: https://github.com/koalaman/shellcheck/wiki/SC2044
for var in $(find XXXXXX)
do
: #some more processing
done
}
# Start the spinner in the background
spinner &
# Get the spinner PID
spinner_pid=$!
#call the function doSomething. Need the progress DOTS till doSomething is executing
doSomething
# Terminate the background running spinner
kill $spinner_pid
# remaining script processing
回答3:
It's not clear from the OP how many files are selected by the find command, and if the do-something has any significant impact on the overall processing time.
Assuming one of the common cases, where (1) find
will scan large number of folders (2) relatively small number of matches and (3) little processing for each file, it is possible to create progress indication by logging directory that are scanned.
If the original find was using find STARTING-POINT ... FIND-EXPRESSION
, the modified command is find STARTING-POINT '(' LOGGING-EXPRESSION ')' -o '( FIND-EXPRESSION ')'
.
Following script will produce a progress report whenever find start scanning a new folder. Note that FIND-EXPRESSION should include explicit '-print', if the original find was relying on the implicit -print.
find STARTING-POINT \
'(' -type d -maxdepth 3 -fprintf /dev/stderr "Processing: %p" ')' \
-o \
'(' FIND-EXPRESSION ')'
# Single Line
find STARTING-POINT '(' -type d -maxdepth N -fprintf /dev/stderr "Processing\n: %p" ')' -oo '(' FIND-EXPRESSION ')'
The above will log each scanned folder (up to N level deep) to stderr.
Example:
# Find all '*.py' files on the system, showing '*' for each folder
find / '(' -type d -fprintf /dev/stderr "*" ')' -o '(' -name '*.py' -print ')'
# Find system '*.so' files, showing each folder scanned
find /lib /usr/lib '(' -type d -fprintf /dev/stderr "Scanning: %p" ')' -o '(' -name '*.so' -print ')'
Additional customization to the logging can be performed - Using the '-regex' or '-path' in the logging filter
来源:https://stackoverflow.com/questions/58447501/progress-bar-while-unix-find-command-is-executing