Differences between revisions 1 and 8 (spanning 7 versions)
Revision 1 as of 2007-05-02 23:34:56
Size: 35
Editor: redondos
Comment:
Revision 8 as of 2009-07-15 18:36:20
Size: 2431
Editor: GreyCat
Comment: Merge FAQ 093 into this one.
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq44)]]
== Removed. ==
<<Anchor(faq44)>>
== 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 [[BashFAQ/005|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 [[BashFAQ/040|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 [[http://www.ivarch.com/programs/pv.shtml|pv]] or [[http://clpbar.sourceforge.net/|clpbar]];
 * use some other tool, e.g. [[http://members.iinet.net.au/~lynx/vcp/|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 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.

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 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.

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