The UNIX and Linux Forums  
Hello and Welcome from United States to the UNIX and Linux Forums! Thank You for Visiting and Joining Our Global Community.

Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
.
google unix.com



Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts and shell scripting languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Help Required: Command to find IP address and command executed of a user loggedout Security 2 08-06-2008 08:12 PM
how to? launch command with string of command line options TinCanFury Shell Programming and Scripting 5 04-28-2008 06:06 PM
inconsistent ls command display at the command prompt & running as a cron job rajranibl SuSE 5 07-30-2007 08:26 AM
How to use more than one MPE command STREAM with Unix command in a single shell? bosskr HP-UX 1 10-16-2006 04:16 PM
How to use more than one MPE command STREAM with Unix command in a single shell? bosskr Shell Programming and Scripting 0 09-19-2006 09:44 PM

Closed Thread
English Japanese Spanish French German Portuguese Italian Dutch Swedish Russian Norwegian Hungarian Hebrew Danish Powered by Powered by Google
 
LinkBack Thread Tools Search this Thread Rate Thread Display Modes
  #1 (permalink)  
Old 07-06-2006
jack1981 jack1981 is offline
Registered User
  
 

Join Date: Jul 2006
Posts: 42
emulating rm command

Hi everyone!

I am trying to write a bash script to emulate the rm command, I want to save all files I delete, a bit like the recycle bin in a windows OS. My script so far is below, I still need to amend a few things, once complete I plan to alias the script to rm and use it as a safe delete method so I don't mess up and delete an important file, the thing is the part I call flow control at the bottom, its real messy and could go on forever, I want to allow for proper rm precedence when using options, can anyone give me advice on how to make a function to manage any options and arguments and reduce the amount of code I have at the bottom?

Any help or comments would be great.

Also, this is my first post so please to meet everyone!

Jack

Code:

#!/bin/bash
# program to emulate the "rm" command in UNIX.


#  CREATE TRASH FOLDER

if ! [ -d "$HOME/deleted" ] ; then
     mkdir $HOME/deleted
fi

# INITIALIZE VARIABLES

NO_ARGS=0
FLAG_R=0
FLAG_F=0
FLAG_I=0
FLAG_V=0
TRASH=$HOME/deleted


# FUNCTIONS

function errorInvalidOpt() {

    echo "rm: invalid option - $o"
    echo "try \`rm -help\` for more information"
    exit 0
}


function errorTooFew() {

   echo "rm: too few arguments"
   echo "try \`rm --help\` for more information"
}

function errorNoSuch() {

   echo "rm: cannot remove $* : no such file or directory"
}

function okDelete() {

echo -n "rm: remove $* ?"
    read ANSWER
    if [ "$ANSWER" = "y" ] ; then
    mv $@ $TRASH
fi
}

function notifyDelete() {

if  [ -f  ] ; then
   echo "removing \`$*'"
   mv $@ $TRASH

fi
}

function  okNotify() {

echo -n "rm: remove $* ?"
    read ANSWER
    if [ "$ANSWER" = "y" ] ; then
    notifyDelete $@

fi
}

function delete() {
   if ! [ -f ] ; then
   errorNoSuch;
   else
   mv  $@ $TRASH
fi
}


# GETOPTS

while getopts :rRfvi o
do    case $o in

           r|R) FLAG_R=1 ;;
             f) FLAG_F=1 ;;
             v) FLAG_V=1 ;;
             i) FLAG_I=1 ;;
             *) errorInvalidOpt

      esac
done
shift `expr $OPTIND - 1`

# FLOW CONTROL

if [ "$#" -eq "$NO_ARGS" ] ; then
   errorTooFew

elif [ $FLAG_R -eq  0 ] && [ $FLAG_F -eq 0 ] && [ $FLAG_I -eq 0 ] && [ $FLAG_V -eq 0 ] ; then
   delete $@

elif [ $FLAG_R -eq  1 ] && [ $FLAG_F -eq 1 ] && [ $FLAG_I -eq 1 ] && [ $FLAG_V -eq 1 ] ; then
   okNotify $@

elif [ $FLAG_R -eq  1 ] && [ $FLAG_F -eq 1 ] && [ $FLAG_I -eq 1 ] ; then
   okNotify $@

elif [ $FLAG_F -eq 1 ] && [ $FLAG_I -eq 1 ] && [ $FLAG_V -eq 1 ] ; then
   okNotify $@

elif [ $FLAG_R -eq  1 ] && [ $FLAG_I -eq 1 ] && [ $FLAG_V -eq 1 ] ; then
   okNotify $@

elif [ $FLAG_R -eq  1 ] && [ $FLAG_V -eq 1 ] ; then
   notifyDelete $@

elif [ $FLAG_V -eq 1 ] && [ $FLAG_I -eq 1 ] ; then
   okNotify $@

elif [ $FLAG_F -eq 1 ] && [ $FLAG_I -eq 1 ] ; then
   notifyDelete $@

elif [ $FLAG_R -eq 1 ] ; then
   delete $@

elif [ $FLAG_V -eq 1 ] ; then
   notifyDelete $@

elif [ $FLAG_I -eq 1 ] ; then
   okDelete $@

elif [ $FLAG_F -eq 1 ] ; then
   delete $@
fi
  #2 (permalink)  
Old 07-06-2006
Hitori's Avatar
Hitori Hitori is offline Forum Advisor  
Registered User
  
 

Join Date: Jun 2006
Posts: 360
getopt

This may help you:
Code:
#!/bin/sh

set -- `getopt "abco:" "$@"`

a= b= c= o=
while :
do
    case "$1" in
    -a) a=1;;
    -b) b=1;;
    -c) c=1;;
    -o) shift; o="$1";;
    --) break;;
    esac
shift
done
shift # get rid of --
# rest of script...
# e.g.
ls -l $@
WARNING: spaces in filenames

It's better to use perl (more safe) and getopts() function in Getopt::Std

Even better is to change the code of original rm and make a hard link to ~/.trash/filename before unlink the file

Last edited by Hitori; 07-06-2006 at 04:21 PM..
  #3 (permalink)  
Old 07-06-2006
jack1981 jack1981 is offline
Registered User
  
 

Join Date: Jul 2006
Posts: 42
Quote:
Originally Posted by Hitori
This may help you:
Code:
#!/bin/sh

set -- `getopt "abco:" "$@"`

a= b= c= o=
while :
do
    case "$1" in
    -a) a=1;;
    -b) b=1;;
    -c) c=1;;
    -o) shift; o="$1";;
    --) break;;
    esac
shift
done
shift # get rid of --
# rest of script...
# e.g.
ls -l $@
WARNING: spaces in filenames

It's better to use perl (more safe) and getopts() function in Getopt::Std

Even better is to change the code of original rm and make a hard link to ~/.trash/filename before unlink the file

Hi,

Thanks for reply, will that give the last option precedence when there is a contradiction of options though?

I am using getops also, I have the script working a bit better but I am stock on precedence.

Thanks again

Mike
  #4 (permalink)  
Old 07-06-2006
jack1981 jack1981 is offline
Registered User
  
 

Join Date: Jul 2006
Posts: 42
got it working, like so:

Code:

#!/bin/bash
# program to emulate the "rm" command in UNIX.
# less the endless sp

#  CREATE TRASH FOLDER

if ! [ -d "$HOME/deleted" ] ; then
     mkdir $HOME/deleted
fi

# INITIALIZE VARIABLES
OPT=-
NO_ARGS=0
FLAG_R=""
FLAG_F=""
FLAG_I=""
FLAG_V=""
TRASH=$HOME/deleted


# FUNCTIONS

function errorInvailidOpt() {

    echo "rm: invalid option - $o"
    echo "try \`rm -help\` for more information"
    exit 0
}


function errorTooFew() {

   echo "rm: too few arguments"
   echo "try \`rm --help\` for more information"
}

function errorNoSuch() {

   echo "rm: cannot remove $* : no such file or directory"
}


function writePro () {
echo -n "rm: remove write-protected file \`$*'?"
read ANSWER
    if [ "$ANSWER" = "y" ] &&  [ "$FLAG_V" = "v" ] ; then
    mv $OPTS $@ $TRASH 2>/dev/null
    echo "removing \`$*'"
    else
    mv $OPTS $@ $TRASH 2>/dev/null

fi
}

function verbose () {
mv $@ $TRASH 2>/dev/null
echo "removing \`$*'"
}
function intVerbose () {
echo -n "rm: remove $* ?"
    read ANSWER
    if [ "$ANSWER" = "y" ] ; then
    mv  $@ $TRASH 2>/dev/null
    echo "removing \`$*'"


fi
}

function int () {
echo -n "rm: remove $* ?"
    read ANSWER
    if [ "$ANSWER" = "y" ] ; then
    mv  $@ $TRASH 2>/dev/null
fi
}

function delete() {
while :
do  case $OPTS in

      v|ivf|vf|ifv|vif) verbose $@
                      break
                      ;;
     vfi|fvi|iv|vi|fiv) intVerbose $@
                      break
                      ;;
               f|fv|if) mv -f $@ $TRASH 2>/dev/null
                      break
                      ;;
                     i) int $@
                      break
                      ;;
                     r)mv $OPTS $@ $TRASH 2>/dev/null
                      break
                      ;;
                     *)mv $@ $TRASH 2>/dev/null
                      break

esac
done

}


# GETOPTS

while getopts :rRfvi o
do    case $o in
           r|R)FLAG_R=""
             ;;
             f) FLAG_F=f
             ;;
             v) FLAG_V=v
             ;;
             i) FLAG_I=i
             ;;
             *) errorInvalidOpt

      esac
done
shift `expr $OPTIND - 1`

# FLOW CONTROL

OPTS=$FLAG_R$FLAG_F$FLAG_I$FLAG_V

if [ "$#" -eq "$NO_ARGS" ] ; then
   errorTooFew $@
elif ! [ -f  "$1" ] &&  ! [ -d "$1" ]; then
   errorNoSuch $@
elif ! [ -w  "$1" ] ; then
   writePro $@
else
   delete $@
fi
  #5 (permalink)  
Old 08-23-2006
olimiles olimiles is offline
Registered User
  
 

Join Date: Aug 2006
Posts: 18
Thats a really useful script Jack, saved me quite a few times now

Did you by any chance finish it so that it does all the directories stuff? ie the

Code:
rm -ir foldername
?

Thanks in advance,

Oliver
  #6 (permalink)  
Old 08-29-2006
jack1981 jack1981 is offline
Registered User
  
 

Join Date: Jul 2006
Posts: 42
Quote:
Originally Posted by olimiles
Thats a really useful script Jack, saved me quite a few times now

Did you by any chance finish it so that it does all the directories stuff? ie the

Code:
rm -ir foldername
?

Thanks in advance,

Oliver
Hi Oliver,
I did finish it.

Here is the final copy.

Code:
#!/bin/bash
# A program to emulate the "rm" command in UNIX.

# INITIALIZE VARIABLES
NO_ARGS=0
FLAG_R=""
FLAG_F_I=""
FLAG_V=""
TRASH=$HOME/deleted

# FUNCTIONS

function errors() {
if [ "$#" -eq  "$NO_ARGS" ] ; then
      echo "rm: too few arguments"
      echo "Try \`rm --help' for more information."
      exit 0
elif [[  ! -f "$1"  && ! -d "$1"   ]] ; then
      echo "rm: cannot remove $ARG : no such file or directory"
      exit 0
elif [[ -d $ARG  &&  "$FLAG_R" = ""  ]] ; then
      echo "rm: \`$ARG' is a directory"
      exit 0
else
     checkExisting $1
fi
}


function checkExisting (){
if [ -d $TRASH/$1 ]; then

     find "$TRASH/$1" -type f -exec shred -fu {} \; 2>/dev/null
     find "$TRASH/$1" -type d -exec rmdir -p  {} \; 2>/dev/null
     directoryDelete $1
else
     directoryDelete $1

fi

}

function directoryDelete () {
if [[ -d "$1"  &&  "$FLAG_R" == "R" && "$FLAG_F_I" == "i" ]]; then
echo -n "rm: descend into directory \`$1'?"
     read A
     if [[ "$A" = [Yy] ]] ; then
echo  "removing all entries of directory \`$1'?"

for FILE in $1/*
do
       if [ -d $FILE ] ; then
       directoryDelete $FILE
   else
       writePro $FILE
fi
done
     echo -n "rm: remove directory \`$1'?"
     read A
     if [[ "$A" = [Yy] ]] ; then
     mv  $1 $TRASH 2>/dev/null
echo "rm: removing directory itself: \`$1'"
fi
fi
else
    writePro $1
fi
}

function writePro () {
if ! [ -w  "$1" ] ; then
echo -n "rm: remove write-protected file \`$*'?"
     read A
     if [[ "$A" = [Yy] ]] ; then
     delete $1
     fi
else
     delete $1
fi

}

function delete() {
if [ "$FLAG_F_I" = "i" ] &&  [ -w  "$1" ] ; then
   interactive $1
elif [ "$FLAG_F_I" = "f"  ] ; then
   force $1
elif [ "$FLAG_R" = "R"  ] ; then
   remove $1
else
   remove $1
fi

}

function force () {

mv -f $1 $TRASH 2>/dev/null
verbose $1
}


function remove () {
mv  $1 $TRASH 2>/dev/null
verbose $1
}

function interactive () {
echo -n "rm: remove $1 ?"
     read A
     if [[ "$A" = [Yy] ]] ; then
     remove $1
     else
     exit 0
fi
}
function verbose () {
if [ "$FLAG_V" = "v" ] ; then
if [ "$FLAG_V" = "v" ] ; then
echo "removing \`$1'"
fi
}


# PARSE OPTIONS WITH GETOPTS

while getopts :rRfvi o
do    case $o in
           r|R) FLAG_R=R
             ;;
             f) FLAG_F_I=f
             ;;
             v) FLAG_V=v
             ;;
             i) FLAG_F_I=i
             ;;
             *) echo "rm: invalid option -$1"
                echo "try \`rm --help' for more information"
                exit 0
      esac
done
shift `expr $OPTIND - 1`

# START OF FLOW

if ! [ -d "$HOME/deleted" ] ; then
     mkdir $HOME/delete
elif  [ $# -eq $NO_ARGS ] ; then
errors
else
   for ARG in $@
   do
   errors $ARG
   done
fi
Regards

Jack
  #7 (permalink)  
Old 08-23-2006
System Shock's Avatar
System Shock System Shock is offline Forum Advisor  
Registered User
  
 

Join Date: May 2006
Location: Tau Ceti V
Posts: 521
Wouldn't it be just easier to simply use the mv command to move the files to whatever you designate the trash directory? Why go thorugh all of the rm simulation pain when essentially what you want to do is move a file from one directory to another?
Closed Thread

Bookmarks

Tags
perl, perl shift, shift, shift perl

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -4. The time now is 08:20 AM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited. Language Translations Powered by .
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios
The UNIX and Linux Forums Content Copyright ©1993-2009. All Rights Reserved.Ad Management by RedTyger

Content Relevant URLs by vBSEO 3.2.0