Differences between revisions 8 and 9
Revision 8 as of 2009-07-15 18:36:20
Size: 2431
Editor: GreyCat
Comment: Merge FAQ 093 into this one.
Revision 9 as of 2009-09-09 18:32:04
Size: 2432
Editor: localhost
Comment: fix typo
Deletions are marked like this. Additions are marked like this.
Line 63: Line 63:
Please note that the "total" of files can change each time rsync enter a directory and finds more/less files that it expected, but at least is more info than cp. Rsync progress is good for big transfers with small files. Please note that the "total" of files can change each time rsync enters a directory and finds more/less files that it expected, but at least is more info than cp. Rsync progress is good for big transfers with small files.

How do I create a progress bar? How do I see a progress indicator when copying/moving files?

The easiest way to add a progress bar to your own script is to use dialog --gauge. Here is an example, which relies heavily on BASH features:

# Bash
# Process all of the *.zip files in the current directory.
files=(*.zip)
dialog --gauge "Working..." 20 75 < <(
   n=${#files[*]}; i=0
   for f in "${files[@]}"; do
      # process "$f" in some way (for testing, "sleep 1")
      echo $((100*(++i)/n))
   done
)

Here's an explanation of what it's doing:

  • An array named files is populated with all the files we want to process.

  • dialog is invoked, and its input is redirected from a ProcessSubstitution. (A pipe could also be used here; we'd simply have to reverse the dialog command and the loop.)

  • The processing loop iterates over the array.
  • Every time a file is processed, it increments a counter (i), and writes the percent complete to stdout.

For more examples of using dialog, see FAQ #40.

A progress bar can also be programmed without any external commands. This example assumes a terminal that uses standard ISO 6429 (a.k.a. ANSI or VT100) escape sequences:

files=(*)
width=$COLUMNS

n=${#files[*]}; i=0
for f in "${files[@]}"; do
  # process "$f" in some way (for testing, "sleep 1")
  printf "\e[40m\e[7m%$(($width*$i/$n))s\n\e[A" " "
  i=$(( $i + 1 ))
done
printf "\e[0m\n"

When copying/moving files

You can't get a progress indicator with cp(1), but you can either:

  • build one yourself with tools such as pv or clpbar;

  • use some other tool, e.g. vcp.

You may want to use pv(1) since it's packaged for many systems. In that case, it's convenient if you create a function or script to wrap it.

For example:

pv "$1" > "$2/${1##*/}"

This lacks error checking and support for moving files.

you can also use the rsync:

rsync -avx --progress --stats "$1" "$2"

Please note that the "total" of files can change each time rsync enters a directory and finds more/less files that it expected, but at least is more info than cp. Rsync progress is good for big transfers with small files.

BashFAQ/044 (last edited 2017-11-13 22:19:11 by GreyCat)