Created
July 24, 2013 22:33
-
-
Save b3niup/6075240 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
### Author: Benedykt 'b3niup' Przybyło | |
USAGE="Usage: ./$0 [options as for regular cp]" | |
#*****************************************************************************# | |
#** Helpers **# | |
#*****************************************************************************# | |
function calc { | |
echo "$1" | bc -l | |
} | |
function round { | |
NUMBER=$1 | |
PREC=$2 | |
if [ -z "$PREC" ]; then PREC=0; fi | |
PREC=$(( $PREC + 1 )) | |
if [ ${NUMBER:0:1} = "." ]; then | |
NUMBER=0$NUMBER | |
fi | |
INT=${NUMBER%%\.*} | |
RES=${NUMBER##*\.} | |
NUMBER="$INT.${RES:0:$PREC}" | |
if [ ${NUMBER:(-1)} -ge 5 ]; then | |
if [ $PREC -eq 1 ]; then | |
NUMBER=${NUMBER:0:(-2)} | |
NUMBER=$(( $NUMBER + 1)) | |
else | |
NUMBER=${NUMBER:0:(-1)} | |
LAST=${NUMBER:(-1)} | |
if [ $LAST = "." ]; then | |
NUMBER=${NUMBER:0:(-1)} | |
LAST=${NUMBER:(-1)} | |
fi | |
NUMBER=${NUMBER:0:(-1)}$(( $LAST + 1 )) | |
fi | |
else | |
if [ $PREC -eq 1 ]; then | |
NUMBER=${NUMBER:0:(-2)} | |
else | |
NUMBER=${NUMBER:0:(-1)} | |
fi | |
fi | |
if [ ${NUMBER:(-1)} = "." ]; then | |
NUMBER=${NUMBER:0:(-1)} | |
fi | |
echo $NUMBER | |
} | |
function size_pretty { | |
# Accepts argument $1 in bytes and returns in human readable format | |
# $2 is optional decimal places resolution | |
SIZE=$1 | |
SCALE=$2 | |
UNITS=(B kB MB GB TB PB EB ZB YB) | |
P=0 | |
if [ -z "$SCALE" ]; then SCALE=2; fi | |
SCALE=$(( $SCALE + 1 )) | |
while [ "`calc "$SIZE / 1024 >= 1"`" -eq 1 ]; do | |
SIZE=`calc "scale=$SCALE; $SIZE / 1024"` | |
P=$(( $P + 1 )) | |
done | |
SIZE=`round $SIZE $SCALE` | |
echo $SIZE${UNITS[$P]} | |
} | |
#*****************************************************************************# | |
#** Main **# | |
#*****************************************************************************# | |
if [ $# -lt 2 ]; then | |
echo $USAGE | |
exit 2 | |
elif [ $# -gt 2 ]; then | |
ARGS=() | |
for ARG in "$@"; do | |
if [ ${ARG:0:1} = "-" ]; then | |
case "$ARG" in | |
-r|-R|--recursive) | |
R=1;; | |
esac | |
continue | |
fi | |
ARGS+=("$ARG") | |
done | |
if [ "${#ARGS[@]}" -gt 2 -a -z "$R" ]; then | |
DIR=${ARGS[$(( ${#ARGS[@]} - 1 ))]} | |
unset ARGS[$(( ${#ARGS[@]} - 1 ))] | |
elif [ $R ]; then | |
DIR=${ARGS[$(( ${#ARGS[@]} - 1 ))]} | |
unset ARGS[$(( ${#ARGS[@]} - 1 ))] | |
fi | |
fi | |
if [ -d "$1" -a -z "$R" ]; then | |
echo "Directory $2 has been ommited" | |
exit 1 | |
fi | |
if [ "$R" ]; then | |
if [ ! -d "${ARGS[0]}" ]; then | |
echo "${ARGS[0]} is not a directory" | |
exit 1 | |
fi | |
TSIZE=`du -s "${ARGS[0]}" | cut -f1` | |
elif [ "$DIR" ]; then | |
TSIZE=0 | |
for FILE in "${ARGS[@]}"; do | |
if [ ! -e "$FILE" ]; then | |
echo "File $FILE does not exist" | |
exit 1 | |
fi | |
FSIZE=`du "$FILE" | cut -f1` | |
if [ $FSIZE ]; then | |
TSIZE=$(( $TSIZE + $FSIZE )) | |
fi | |
done | |
else | |
if [ ! -e "$1" ]; then | |
echo "File $1 does not exist" | |
exit 1 | |
fi | |
TSIZE=`du "$1" | cut -f1` | |
fi | |
TPSIZE=`size_pretty $(( $TSIZE * 1024 )) 1` #total pretty size | |
if [ $TSIZE -gt 1048576 ]; then | |
SLEEP=1 | |
elif [ $TSIZE -gt 102400 ]; then | |
SLEEP=0.5 | |
else | |
SLEEP=0.1 | |
fi | |
cp "$@" & | |
PID=$! | |
trap "kill -SIGTERM $PID; exit" SIGINT | |
trap "kill -SIGTERM $PID; exit" SIGTERM | |
OLD_WIDTH=`tput cols` | |
while [ 1 ]; do | |
if [ -z "$(ps -p $PID | grep $PID)" ]; then | |
if [ $BREAK ]; then | |
break | |
else | |
BREAK=1 | |
fi | |
fi | |
if [ $R ]; then | |
CSIZE=`du -s "$DIR/${ARGS[0]##*/}" 2> /dev/null | cut -f1` | |
elif [ "$DIR" ]; then | |
CSIZE=0 | |
for FILE in "${ARGS[@]}"; do | |
FSIZE=`du "$DIR/${FILE##*/}" 2> /dev/null | cut -f1` | |
if [ $FSIZE ]; then | |
CSIZE=$(( $CSIZE + $FSIZE )) | |
fi | |
done | |
else | |
if [ -d $2 ]; then | |
CSIZE=`du "$2/${1##*/}" 2> /dev/null | cut -f1` | |
else | |
CSIZE=`du "$2" 2> /dev/null | cut -f1` | |
fi | |
fi | |
WIDTH=`tput cols` | |
CPSIZE=`size_pretty $(( $CSIZE * 1024 )) 1` #copied pretty size | |
ILEN=$(( ${#CPSIZE} + 7 + ${#TPSIZE} )) #length of everything except progress bar | |
PBLEN=$(( $WIDTH - $ILEN )) #progress bar length | |
PERC=`calc "$CSIZE / $TSIZE * 100"` | |
PERC=`round $PERC` | |
PLEN=`calc "$PERC / 100 * $PBLEN"` #progress length | |
PLEN=`round $PLEN` | |
echo -en "\r[" | |
for i in `seq 1 $PLEN`; do echo -n "#"; done | |
for i in `seq 1 $(( $PBLEN - $PLEN ))`; do echo -n "-"; done | |
echo -n "] $CPSIZE / $TPSIZE " | |
if [ $OLD_WIDTH -gt $WIDTH ]; then | |
for i in `seq 1 $(( $OLD_WIDTH - $WIDTH ))`; do echo -n " "; done | |
fi | |
OLD_WIDTH=$WIDTH | |
sleep $SLEEP | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
nice!