Register
It is currently Sun Dec 21, 2014 9:05 pm

Visual cp command ( vicp )


All times are UTC - 6 hours


Post new topic Reply to topic  [ 3 posts ] 
Author Message
 PostPosted: Sun Jul 31, 2011 11:24 am   
User avatar

Joined: Sat Jul 02, 2011 10:43 am
Posts: 23
Location: Devon,UK
I do a lot of video work so as you can imagine the files can be very big, the standard cp -v command doesn't really give a lot of extra info so I knocked up this script to show a dialog box with file copy progress and overall progress so I can see whats going on with the cp command, all normal cp switches are passed to the cp command ( which is run in the background so this script doesn't slow it up too much ) there is also an extra switch "-X" which will not display a dialog box but give command line output, just replace "cp" with "vicp" and you're good to go ( presuming you have named this script "vicp", made it executable and placed it somwhere in your path ).
Small update to correct occasional screwing up of dest file structure.
Updated version here:
http://keithhedger.freetzi.com/bashscripts/vicp
Rather than keep editing this post.
Code:
#!/bin/bash

trap "leave" EXIT HUP INT TERM KILL
export DIALOGOPTS="--backtitle \"ViCp\""

leave ()
{
#make sure all the lights are off
   if [ ! -z $DIAPID ];then
      tput cup $(($(tput lines)-1)) 0
      echo  "//@@EOF@@//" >$FIFO
   fi
   rm $FIFO 2>/dev/null
   kill -9 $CPPID $DIAPID  2>/dev/null
}

DATAARRAY=""
NOGRAPH=0
RECURSE=0
ARRAYCNT=0
DIAPID=""
TOTALFILES=0
CURRENTFILE=0
SIMULATE=0

#'cos I'm anal that way!
prettyprint ()
{
   local RETVAL="$1"

   if [ ! -z "$RETVAL" ];then
      RETVAL=${RETVAL#./}
      RETVAL="${RETVAL%/}"

      if [ "$RETVAL" = "." ];then
         RETVAL="$PWD"
      fi

      if [ "${RETVAL:0:1}" != "/" ];then
         RETVAL="$PWD/$RETVAL"
      fi
   fi
   echo "$RETVAL"
}

#check some stuff before doing the copy
sanitycheck ()
{
   if [ ${#DATAARRAY[@]} -gt 2 ] && [ ! -d ${DATAARRAY[ARRAYCNT - 1]} ];then
      echo "vicp: target is not a directory"
      exit -1
   fi

   if [ $RECURSE -eq 0 ];then

      for (( CNT=0;CNT<(( $ARRAYCNT - 1 ));CNT++ ))
         do
#non-fatal error dont copy directories unless using recurse
            if [ -d "${DATAARRAY[$CNT]}" ];then
               echo "vicp: omitting directory ${DATAARRAY[$CNT]}"
               DATAARRAY[$CNT]=""
            fi
         done
   fi

   for (( CNT=0;CNT<ARRAYCNT-1;CNT++ ))
      do
         if [ ! -e "${DATAARRAY[$CNT]}" ];then
            echo "vicp: cannot stat ${DATAARRAY[$CNT]} : No such file or directory"
            exit -1
         fi
         DATAARRAY[$CNT]=$(prettyprint "${DATAARRAY[$CNT]}")
         TOTALFILES=$((TOTALFILES+$(find "${DATAARRAY[$CNT]}" ! -type d |wc -l)))
      done

   OUT=$(prettyprint "${DATAARRAY[$CNT]}")
}

#Check command line parameters
doparams ()
{
   local PARAMS CNT

   for PARAMS in "$@"

      do
         case $PARAMS in

         -[[:alnum:]]*)
            for (( CNT=1;CNT<${#PARAMS};CNT++ ))
               do
#peel off -r and -X
                  if [ ${PARAMS:CNT:1} = "r" -o ${PARAMS:CNT:1} = "R" ];then
                     RECURSE=1
                     continue
                  fi
                  if [ ${PARAMS:CNT:1} = "X" ];then
                     NOGRAPH=1
                     continue
                  fi
#EVALSTRING is eventually passed to the "real" cp command
                  EVALSTRING="${EVALSTRING} -${PARAMS:CNT:1}"
               done
            ;;

#we do recursive
         --recursive)
            RECURSE=1
            ;;

#just checking
         --simulate)
            SIMULATE=1
            NOGRAPH=1
            ;;

         --[[:alnum:]]*)
            EVALSTRING="${EVALSTRING} ${PARAMS}"
            ;;
         
         *)
            DATAARRAY[$ARRAYCNT]="${PARAMS}"
            (( ARRAYCNT++ ))
            ;;
         esac
      done
}

#main cp routine
docp ()
{   
   local TOSIZE PERCENT

#either do a fancy dialog output
   if [ $NOGRAPH -eq 0 ];then
      while (( FROMSIZE>TOSIZE )) && ps $CPPID &>/dev/null
         do
            TOSIZE=$(stat "$2" 2>/dev/null |grep Size|awk '{print $2}')
            TOSIZE=${TOSIZE:-0}

            PERCENT=$(echo "scale=2 ;100/($FROMSIZE/($TOSIZE+1))"|bc -l 2>/dev/null )
            PERCENT=${PERCENT%.?*}
            if (( PERCENT>100 ));then
               PERCENT=100
            fi
#if only copying one file then no overall progress bar
#from file=$1 to file =$2
            if [ $TOTALFILES -gt 1 ];then
               echo "$1@$2@$TOSIZE@$FROMSIZE@$CURRENTFILE@$PERCENT" >$FIFO
            else
               echo "$1@$2@$TOSIZE@$FROMSIZE@$PERCENT" >$FIFO
            fi
         done
#or a dull command line output
   else
      while (( FROMSIZE>TOSIZE )) && ps $CPPID &>/dev/null
         do
            TOSIZE=$(stat "$2" 2>/dev/null |grep Size|awk '{print $2}')
            TOSIZE=${TOSIZE:-0}
            PERCENT=$(echo "scale=2 ;100/($FROMSIZE/($TOSIZE))"|bc -l 2>/dev/null )
            echo -en "\rCopied ${TOSIZE}B of ${FROMSIZE}B (${PERCENT%.?*}%) to $2"
         done
   fi

#just clean up command line output
   if [ $NOGRAPH -eq 1 ];then

      TOSIZE=$(stat "$2" 2>/dev/null |grep Size|awk '{print $2}')
      TOSIZE=${TOSIZE:-0}

      if [ "$FROMSIZE$TOSIZE" = "00" ];then
         PERCENT=100
      else
         PERCENT=$(echo "scale=2 ;100/($FROMSIZE/($TOSIZE))"|bc -l 2>/dev/null )
      fi

      echo -e "\rCopied ${TOSIZE}B of ${FROMSIZE}B (${PERCENT%.?*}%) to $2"
   fi
}

#the bit does the actual copying
dovicp ()
{
   local TONAME="$2"

#cp is run in the back ground

   if [ $SIMULATE -eq 1 ];then
      echo "cp $EVALSTRING \"$1\" \"$TONAME\""
      return
   else
      cp $EVALSTRING "$1" "$TONAME" &
   fi

   CPPID=$!
   FROMSIZE=$(stat "$1" 2>/dev/null |grep Size|awk '{print $2}')

   if [ -d "$2" ];then
      TONAME="$TONAME/$(basename "$1")"
   fi

   (( CURRENTFILE++ ))
   if [ $NOGRAPH -eq 1 ] && [ $TOTALFILES -gt 1 ];then
      echo "File $CURRENTFILE of $TOTALFILES"
   fi

#run the output stuff   
   docp "$1" "$TONAME"
}

#set up the overall progress bar
setupoverbar ()
{
   FROMBAR="                             "
   BAR=""

   BARSIZE=$(($(tput cols)-10))
   while (( ${#FROMBAR}<BARSIZE ))
      do
         FROMBAR="${FROMBAR}${FROMBAR}"
      done
   FROMBAR=${FROMBAR:0:$(($BARSIZE-12))}
   MID=$(((BARSIZE/2)-5))
}

#main loop takes care of recursion
main ()
{
#simple case
   if [ $RECURSE -eq 0 ] && [ $ARRAYCNT -eq 2 ];then
      dovicp "${DATAARRAY[0]}" "${DATAARRAY[1]}"
      exit 0
   fi

   for (( CNT=0;CNT<(( $ARRAYCNT - 1 ));CNT++ ))
      do

#dropped bad file name passed on command line
         if [ -z "${DATAARRAY[$CNT]}" ];then
            continue
         fi

#if its a directory then recurse
         if [ -d "${DATAARRAY[$CNT]}" ];then
            TOFOLD=$(basename "${DATAARRAY[$CNT]}")
            TOUT="${OUT}/${TOFOLD}"
            cd "${DATAARRAY[$CNT]}"
            find -mindepth 1 -type d -exec mkdir -p "${TOUT}"/'{}' \;
            while read
               do
                  FROMFILE=$(prettyprint "$REPLY")
                  TOFILE="${OUT}/$(basename "${DATAARRAY[$CNT]}")${FROMFILE##"${DATAARRAY[$CNT]}"}"
                  dovicp "$FROMFILE" "$TOFILE"
               done < <(find  ! -type d)
            cd $OLDPWD
#else just a file copy
         else
            dovicp "${DATAARRAY[$CNT]}" "$OUT/$(basename "${DATAARRAY[$CNT]}")"
         fi
      done
}

#run the dialog in the background
rundialog ()
{
#taller dialog for multifile copy
   if [ $TOTALFILES -gt 1 ];then
      HEIGHT=11
   else
      HEIGHT=8
   fi

   (
   while [ -e $FIFO ]
      do
         read <$FIFO      

#time to go
         if [ X"$REPLY" = X"//@@EOF@@//" ];then
            exit 0
         fi

#print fancy stuff in the dialog box
         echo "XXX"
         if [ $(echo "$REPLY"|awk -F "@" '{print NF }') -gt 5 ];then
            CURRENTFILE=$(echo "$REPLY"|awk -F "@" '{print $5}')

#dialog won't let me have two bars so roll my own
            TOTSLICES=$(echo "scale=2 ;($BARSIZE/$TOTALFILES*$CURRENTFILE)+0.5"|bc -l 2>/dev/null)
            TOTSLICES=${TOTSLICES%.?*}

            PERCENT=$(echo "scale=2 ;100/($TOTALFILES/$CURRENTFILE)"|bc -l 2>/dev/null )
            PERCENT=${PERCENT%.?*}
            PERCENT=${PERCENT:-0}

            BAR="${FROMBAR:0:$MID}${PERCENT}%${FROMBAR:$MID:$BARSIZE}"
            TOBAR="\Zb\Z3\Zr  ${BAR:0:$((TOTSLICES))}\Zn\Z3\Zb${BAR:$((TOTSLICES)):$(( BARSIZE-(TOTSLICES) ))}"

            echo "\Zb\Z3File \Zn$CURRENTFILE \Zb\Z3of \Zn$TOTALFILES"
            echo "\Zb\Z3Overall Progress\Zn"
            echo "$TOBAR"
         fi
         echo "$REPLY"|awk -F "@" '{print "\\Zb\\Z3From:\\Zn"$1}'
         echo "$REPLY"|awk -F "@" '{print "\\Zb\\Z3To:\\Zn"$2}'
         echo "$REPLY"|awk -F "@" '{print "\\Zb\\Z3Copied \\Zn" $3 "B \\Zb\\Z3of \\Zn" $4 "B"}'
         echo "XXX"
         echo "$REPLY"|awk -F "@" '{print $NF }'

      done |dialog --colors --title "Copying..." --no-collapse --gauge "" $HEIGHT $(($(tput cols)-10))

#run it in the background as a sub proccess
   )&
   DIAPID=$!
}

#lets get going
setterm -msg off
doparams "$@"
sanitycheck
FIFO=$(tempfile)
mkfifo $FIFO 2>/dev/null
#TOTALFILES=34
setupoverbar


if [ $NOGRAPH -eq 0 ];then
   rundialog
fi

main
leave


Last edited by Keith Hedger on Mon Dec 12, 2011 12:53 pm, edited 2 times in total.

Top
 Profile WWW  
 PostPosted: Thu Aug 11, 2011 8:47 am   
Moderator
User avatar

Joined: Thu Oct 11, 2007 7:12 am
Posts: 229
Location: London - UK
I recommend you have a little look at the rsync command :) It can give various stats and progress info and handles multiple types of copying.


Top
 Profile  
 PostPosted: Fri Aug 12, 2011 6:33 am   
User avatar

Joined: Sat Jul 02, 2011 10:43 am
Posts: 23
Location: Devon,UK
DarthWavy wrote:
I recommend you have a little look at the rsync command :) It can give various stats and progress info and handles multiple types of copying.


Don't need rsync, does TOO much I don't need to sync folders just do a lot of moving about of data and wanted to know what was going on, thanks for the suggestion anyway.


Top
 Profile WWW  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP