LinuxQuestions.org
Share your knowledge at the LQ Wiki.
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 10-25-2010, 05:03 AM   #16
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556

Quote:
Originally Posted by grail View Post
GGirl .. sorry to hijack this thread a little .. just trying to wrap my head around it
Not at all- I'm finding all discussion in here to be interesting and relevant, and the more info the better. I seem to agree with (I think it was you) above that `getopts` is working as it is supposed to -- the issue (I believe) is that I want functionality that it is not supposed to do, or in other words, I want it to read minds.

I'm still pondering this and reading (and appreciating) all input in this situ so please feel free to continue discussions.

(I still have yet to read all that has been added to the thread since yesterday.)

Last edited by GrapefruiTgirl; 10-25-2010 at 05:04 AM.
 
Old 10-25-2010, 07:07 AM   #17
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
@crts - thanks again as I agree that the trouble to process the single 'like to have' option is far outweighed by the level of difficulty to make it happen

@GGirl - thanks for being patient

I believe crts' solution to include equals is the best option and that it allows you to then formulate an appropriate response should the user not do so.

I look forward to seeing which way you choose
 
Old 10-26-2010, 08:28 AM   #18
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Lightbulb nice input for getopts

This isn't likely my final post to this thread. I have yet to re-read all the input provided above; but on what I have read, and on my experimenting, I conclude that shell getopts doesn't do what I want in every case.
I've tried a bunch of workarounds, including about 10 lines of sed expressions and a bunch of other crap to pre-process the CLI args, but it was still not working right and getting ridiculous.

I have what I think is the solution, but it won't necessarily work *exactly* like this for someone with slightly different requirements, but down below I demonstrate how it can work for that.

To summarize the problem:

My requirement was that an optional argument "R" can accept an optional numeric value, and "R" is the only option that accepts an optional value of any kind. I wanted the "R" and its value to be able to be given in *any* format on the commandline, and be interpreted correctly. This wasn't working because depending on whether R's value immediately followed "R", and/or was separated by a space, and/or was followed immediately by other options or by a space and other options, the outcome for "R" and its value were unpredictable/unreliable. I'd like to have --long-opts too, but they're a frivolity I can do without at the moment.
Making options that require arguments, require an "=" sign, was not agreeable to me. So, here's what I've got:

Code:
while getopts ":l.#vhAabcdkpPswz1234567890" OPT ${ARGV}; do
 case $OPT in
          l) BASENAME="no" ;;
        '.') NAMEOPT="-name"; DOTOPT="*" ;;
        '#') SHEBANG="yes" ;;
#          v) VERBOSE='1' ;;
          h) help; exit 0 ;;
          A) add_shell all ;;
          a) add_shell ash ;;
          b) add_shell bash ;;
          c) add_shell csh ;;
          d) add_shell dash ;;
          k) add_shell ksh ;;
          p) add_shell perl ;;
          P) add_shell python ;;
          s) add_shell sh ;;
          w) add_shell awk ;;
          z) add_shell zsh ;;
      [0-9]) Ropt="${Ropt}${OPT}" ;;
          *) echo "Invalid parameter: -${OPTARG:-$OPT}" >&2; exit 1 ;;
 esac
done

if [ -n "${Ropt}" ]; then
        if [ $((${Ropt})) -ge 2 ]; then
                MAXDEPTH="-maxdepth ${Ropt}"
        elif [ $((${Ropt})) -eq 0 ]; then
                unset MAXDEPTH
        fi
fi
So, I've removed "R" as a CLI option, but have added [0-9] as CLI options. All options are given together in one string beginning with a "-".
The feature of the program that is controlled by the "R" value (we'll call it the "R part"), is still present and still has its default setting of 1. But now, it retains its default setting unless any digits are given in the CLI arg-string. Digits given on the CLI are concatenated into a (string) integer number which is then evaluated after getopts is done. If the resulting integer number is just a "0", the "R part" of the program is disabled. If the integer number is >=2 then the "R part" is adjusted accordingly.

I figure, if a person were to want to use this method for multiple "R" possibilities, it would be easy enough. Let's say it's like my situation, but you have "R" and "X", which can each take optional numeric arguments. Let's say the CLI receives:
-abR2cdX5
During the getopts loop:
1) R is found, turning a flag on. The flag says "any upcoming digits will concat onto the R string".
2) 2 is found,so Rstring:=2
3) c is found, d is found.. X is found. If R flag is on, turn it off. So Rstring=2. Turn on X flag.
4) Now any upcoming digits concat onto X string.
5) etc.. etc... eventually Rstring=2 and Xstring=5 when done looping.

So this is what I'm going to use I think. It's really simple to parse the input, and reliable. Feedback welcome! And meanwhile, thank you to everyone who has contributed here, and who adds anything further too.
 
Old 10-26-2010, 09:23 AM   #19
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
So just thought I would throw in some formats I like to use:
Code:
[0-9]) Ropt="${Ropt}${OPT}" ;;

# becomes

[0-9]) Ropt+=$OPT;;

++++++
if [ -n "${Ropt}" ]; then
        if [ $((${Ropt})) -ge 2 ]; then
                MAXDEPTH="-maxdepth ${Ropt}"
        elif [ $((${Ropt})) -eq 0 ]; then
                unset MAXDEPTH
        fi
fi

# becomes

if [[ $Ropt ]]
then
    if (( Ropt >= 2 ))
    then
        MAXDEPTH="-maxdepth $Ropt"
    elif (( Ropt == 0 ))
    then
        unset MAXDEPTH
    fi
fi
Mainly I just think the (()) structure looks a little easier to read and lets you know straight away it is number stuff
 
1 members found this post helpful.
Old 10-26-2010, 09:32 AM   #20
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Hmm, yes I like the (( .. )) for integer tests, provided it isn't bash dependant. However, this here:

Code:
Ropt+=$OPT
has had me befuddled for some time. Usually (and so I thought here) this is an addition operator. Numerous times I used to wonder why it was failing to do addition (in the shell) when I wanted it to. Just now, thanks to your feedback, I see it's a concatenation operator. That explains why you never see that operator in my code. :/
 
Old 10-26-2010, 09:59 AM   #21
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
Actually it can be quite a tricky one:
Code:
Ropt+=$OPT # Concatenate strings

Ropt+=($OPT) # Append to Array

((Ropt+=$OPT)) # Add value $OPT to Ropt
 
1 members found this post helpful.
Old 10-27-2010, 05:46 AM   #22
salasi
Senior Member
 
Registered: Jul 2007
Location: Directly above centre of the earth, UK
Distribution: SuSE, plus some hopping
Posts: 4,070

Rep: Reputation: 897Reputation: 897Reputation: 897Reputation: 897Reputation: 897Reputation: 897Reputation: 897
Quote:
Originally Posted by GrapefruiTgirl View Post
Anyhow, while I question whether there's really anything to gain by using getopts over manually dealing with options
I know what you mean; I spent ages trying to work out whether 'getopts' was really an advantage, or whether I was just shuffling off any ugliness in the code somewhere else; in the end, the only way to make progress was to try it and see how the final code looked.

Quote:
For the record:
1) this is Bash shell at this time, but will be Dash ultimately.
2) /bin/getopt doesn't work like this one - I can't make it work at all. Does it ever work? Should I be using that instead?
No to getopt rather than getopts: getopt is older and is less suitable for doing 'fancy stuff' than getopts.

Dash, I know nothing about, so can't comment.

By now, you probably know most of this, but hey, a tutorial never hurts!
http://bashcurescancer.com/the-60-se...-tutorial.html
http://www.bash-hackers.org/wiki/dok...topts_tutorial
http://www.shelldorado.com/goodcoding/cmdargs.html
http://aplawrence.com/Unix/getopts.html

I think one of those suggests that getopts doesn't work with long options.
 
1 members found this post helpful.
Old 10-27-2010, 06:00 AM   #23
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Thanks salasi, yes, more tutorials are never a bad idea, and I will look at those links you gave. One I recognize already: bashcurescancer - I have been there before (and will be there again!). The others I don't yet recognize but will be looking at.

The Dash/Bash difference would only be relevant if the built-in getopts was different between the two. And at this time, I'm not sure if they are or not. In the interest of portability, I would not want to depend on Dash any more than I like to write Bash-dependant code. I did read here and there that /bin/getopt is inferior to getopts, and that's unfortunate, as that's something that would be probably more poratble to use in code than a shell built-in. Anyhow, I have both Bash and Dash so I can test on both. Who knows, this program I'm writing is not extremely useful or widely interesting, so in the end it may only have to work right for me. You guys'll probably laugh if you know what this program (merely) does. But it keeps be occupied.

As for long opts, I think that if I wanted to use them (as well as short opts), I would just not use getopts at all, I think I'd just do it the old fashioned way. I have no problem with that, but sometimes it's funny, like this time: the program I'm working on is pretty small and relatively non-complicated, so I find it peculiar spending (for example) 50-100 lines of code parsing options for a program that totals 125 lines. And when that 50-100 lines remains the same,. or gets longer by using getopts, well the end doesn't justify the means. :/

Thanks for the input salasi.
 
  


Reply

Tags
bash, dash, getopt, getopts, shell



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
how to pass command-line parameter to shell script? Kropotkin Linux - Newbie 12 07-25-2011 09:24 AM
Regarding # /opt/CTEact/bin/act & /opt/SUNWexplo/bin/explorer not available for x86 rajaniyer123 Solaris / OpenSolaris 6 04-24-2008 09:09 AM
Writing a Shell Script with a Time Parameter Siva4Linux Linux - Wireless Networking 2 02-05-2007 06:56 AM
linux bash - how to use a dynamic parameter in shell parameter expansion expression nickleus Linux - General 2 08-21-2006 04:54 AM
How to change parameter values of a function in shell script? Bassam Programming 0 01-25-2004 09:52 AM

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

All times are GMT -5. The time now is 04:51 PM.

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