LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-13-2006, 12:56 PM   #1
mike9287
Member
 
Registered: May 2006
Location: North England
Distribution: Mandriva
Posts: 64

Rep: Reputation: 15
struggling with getopts


Hi I am trying to use getopts in a script which acts like the "rm" command in UNIX, my script is below, its not complete, I have added an extra case statement to deal with precedence and even though it works its not a very good way to go about things, I feel I am under using getopts and that I am wasting porcessor power in the second case statment to check the combination of options and act accordingly.

Here is my script:

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=""
FLAG_F=""
FLAG_I=""
FLAG_V=""
TRASH=$HOME/deleted


# FUNCTIONS

function errorInvalidOpt() {

    echo "rm: invalid option - $1"
    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
    delete $@
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 $@ $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
The way I worked it was to flag each option as it was parsed by getopts and then add all flags which were actioned to a varible called $OPTS and then send that to a second case statement to check the combination and act act accordingly.

How can I use getopts to determine which option is last on the command line and has precedence where contradiction is concerned, I will be improving thr rest of the script and hope to reduce a lot of code and make it neater, for now I need help on the precedence before I fix the rest of the script.

Thanks

Mike

Last edited by mike9287; 07-13-2006 at 12:58 PM.
 
Old 07-13-2006, 01:29 PM   #2
raskin
Senior Member
 
Registered: Sep 2005
Location: France
Distribution: approximately NixOS (http://nixos.org)
Posts: 1,900

Rep: Reputation: 69
Doesn't getopts just proceed options in order of their appearance, so you can have a variable for every conflict and toggle it one side or other on every encounter of any of two options?
 
Old 07-13-2006, 02:08 PM   #3
mike9287
Member
 
Registered: May 2006
Location: North England
Distribution: Mandriva
Posts: 64

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by raskin
Doesn't getopts just proceed options in order of their appearance, so you can have a variable for every conflict and toggle it one side or other on every encounter of any of two options?

Hi thanks for the reply,

could you give me and example of what you mean, I think I have something similar in the case statment but its messy, I can figure out a simpler way to do it.

Cheers

Mike
 
Old 07-13-2006, 02:14 PM   #4
raskin
Senior Member
 
Registered: Sep 2005
Location: France
Distribution: approximately NixOS (http://nixos.org)
Posts: 1,900

Rep: Reputation: 69
I_F_FLAG=_;

while getopts :if o; do
case $o in
i) I_F_FLAG=I
;;
f) I_F_FLAG=F
;;
esac;
done

Last edited by raskin; 07-13-2006 at 02:15 PM.
 
Old 07-13-2006, 02:27 PM   #5
mike9287
Member
 
Registered: May 2006
Location: North England
Distribution: Mandriva
Posts: 64

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by raskin
I_F_FLAG=_;

while getopts :if o; do
case $o in
i) I_F_FLAG=I
;;
f) I_F_FLAG=F
;;
esac;
done

thanks again, but for more options wouldnt that mean only the last option took precedence and the others would be ignored?

like if I use, myabe 3 option arguments and 2 of them need to be actioned like interactive and verbose wouldnt that only process the last one?

like if i use options -fiv it should say

rm : remove filename?

and then I enter y/Y

and it should then say

removing filename

but if the I_F_FLAG holds only 1 value then I cant do more than one thing for multiple options

its fried my brain thinking of ways round this, the extra case statment works with a little more work but i want to reduce the code and processing time as much as possible.

Thanks

Mike
 
Old 07-13-2006, 02:35 PM   #6
mike9287
Member
 
Registered: May 2006
Location: North England
Distribution: Mandriva
Posts: 64

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by raskin
I_F_FLAG=_;

while getopts :if o; do
case $o in
i) I_F_FLAG=I
;;
f) I_F_FLAG=F
;;
esac;
done
Hey, I think this might work (need to test it):

Code:
while getopts :rRfvi o
do    case $o in
           r|R) FLAG_R=r ; PREC=r
             ;;
             f) FLAG_F=f ; PREC=f
             ;;
             v) FLAG_V=v ; PREC=v
             ;;
             i) FLAG_I=i ; PREC=i
             ;;
             *) echo "rm: invalid option -$1"
                echo "try \`rm --help' for more information"
                exit 0
then I can keep my flags and PREC for precedence will only have the value of the last option, I can then use that value in my functions to determine which option was last and act accordingly (i think).

Thanks for the info!

Mike
 
Old 07-14-2006, 12:42 AM   #7
raskin
Senior Member
 
Registered: Sep 2005
Location: France
Distribution: approximately NixOS (http://nixos.org)
Posts: 1,900

Rep: Reputation: 69
No, you can't. At least in general case. Consider 'rm -ririv aaa;'. I meant, if you had -i/-f and -v/-q pairs, you would make FLAG_I_F and FLAG_V_Q. If some option -r doesn't conflict with anything, make FLAG_R.
 
  


Reply



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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Struggling with Math, need help randyriver10 General 45 08-28-2007 05:27 AM
Really struggling with ATI crimsontide Linux - Hardware 1 02-01-2006 10:33 PM
Mandatory arguments with getopts? rose_bud4201 Programming 2 03-10-2005 02:18 PM
getopts multiple parameters arnulfo Programming 2 12-23-2004 05:12 AM
Help with getopts command Rezon Programming 3 10-22-2003 04:12 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:29 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration