Skip to content

Instantly share code, notes, and snippets.

@jonhoo
Created April 7, 2011 01:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonhoo/906883 to your computer and use it in GitHub Desktop.
Save jonhoo/906883 to your computer and use it in GitHub Desktop.
A busybox bash script for determining the progress of a copy operation
A simple script that estimates the progress, speed and probable completion time of a copy operation.
It was originally written for a QNAP NAS running busybox, but should be compatible with any busybox install.
Should also work for most Linux systems, but the options to du and df will have to be modified since the busybox uses a simplified syntax (The -m for both of them is to get the output in MB).
The script is called with the same arguments given to cp
The script estimates by using:
- Difference in df-used for speed
- Difference in du for percentage
- A combination of the above for ETC (Estimated Time to Completion)
#!/bin/bash
SLEEPTIME=10
SOURCE="$1"
DEST="$2"
if [[ "$SOURCE" == "" || "$DEST" == "" ]]; then
echo "Usage: $0 <source> <destination>"
exit 1
fi
echo -n "Collecting initial data..."
# Get some initial readings
# Size of dataset we're copying
SOURCESIZE=`du -ms $SOURCE | awk '{print \$1}'`
# Initial size of destination
FIRSTSIZE=`df -m $DEST | grep -v Filesystem | awk '{print \$3}'`
# Starttime
FIRST=`date +%s`
echo -en " DONE\nWaiting $SLEEPTIME seconds before collecting first statistics..."
sleep "$SLEEPTIME"
echo -e " DONE\nMonitoring progress every $SLEEPTIME seconds"
while [ 1 ]; do
# How much has been copied?
DSIZE=`du -ms $DEST | awk '{print \$1}'`
# How large is the destination drive now?
# Note that this in inaccurate since we might be
# the only operation modifying the data on the drive!
# It is still better than doing using DSIZE, since
# DSIZE will not report info about files that have not
# been copied completely yet.
DBLOCKS=`df -m $DEST | grep -v Filesystem | awk '{print \$3}'`
# How much has been written to the drive?
WRITTEN=$(($DBLOCKS - $FIRSTSIZE))
# How much do we have left to write?
REM=$(($SOURCESIZE - $DSIZE))
# And that's how many percent?
# Note that bash does not have floating point artithmetic
PERC=$((100 * $DSIZE / $SOURCESIZE))
# How much time has passed?
TDIFF=$((`date +%s` - $FIRST))
# Make sure we don't get any divisions by zero
if [[ $TDIFF -ne 0 && $WRITTEN -ne 0 ]]; then
SPD=$(($WRITTEN / $TDIFF))
# If nothing is written, we can exit
if [[ $SPD -eq 0 ]]; then
if [[ $PERC -eq 100 ]]; then
echo "\rDone! "
exit 0
else
echo "\rSpeed has reached 0, is something wrong? "
fi
else
# Remaining seconds
TREM=$(($REM / $SPD))
# Prettify the remaining time
ETCH=$(($TREM / 3600))
ETCM=$(($TREM % 3600 / 60))
ETCS=$(($TREM % 60))
ETC="$ETCH h, $ETCM m, $ETCS s"
# Show progress!
printf "\r%d%% at %.1f MB/s (%d of %d MB, ETC: %s) " "$PERC" "$SPD" "$DSIZE" "$SOURCESIZE" "$ETC"
fi
fi
# We don't want to overload the system with our infinite loop
sleep "$SLEEPTIME"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment