Progress bar while Unix find command is executing

試著忘記壹切 提交于 2019-12-11 16:12:47

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!