Identify problem with while getopts


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Identify problem with while getopts
# 1  
Old 07-30-2016
Identify problem with while getopts

can anyone spot a problem with the below:

Code:
$ 
$ cat getopts.sh                                                                                                                               
#!/bin/sh

usage() { echo "myscript.sh local /tmp data.txt 600s -query" 1>&2; exit 1; }

while getopts ":::::::::::::i:e:" o; do
    case "${o}" in
        i)
            i=${OPTARG}
                if awk -v TOPTION="${i}" 'BEGIN{ if (TOPTION ~ /include:/) {exit 0} else {exit 1} }' ; then
                        echo "${i}"
                else
                        usage
                fi
            ;;
        e)
            e=${OPTARG}
                if awk -v TOPTION="${e}" 'BEGIN{ if (TOPTION ~ /exclude:/) {exit 0} else {exit 1} }' ; then
                        echo "${e}"
                else
                        usage
                fi
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))

if [ -z "${i}" ] || [ -z "${e}" ]; then
    usage
fi

echo "i = ${i}"
echo "e = ${e}"
$ 
$ 
$ 
$ ./getopts.sh local /tmp data.txt 50s -query -i include:
myscript.sh local /tmp data.txt 600s -query
$ 
$ 
$ ./getopts.sh -i include:                               
include:
myscript.sh local /tmp data.txt 600s -query
$ 
$

i only seem to get the expected output IF i specify just the "-i include", without anything else.

how can this be fixed? what am i doing wrong? i want to be able to specify the "-i" or "-e" or any additional arguments, wherever i want on the command line. how is this possible?
i need this to be portable as i'll be using it across many platforms.
# 2  
Old 07-31-2016
It is not! According to the standards, options must be specified on the command line BEFORE operands.

Furthermore, I have no idea why you have so many colons in the first argument passed to getopts??? Are you trying to say that you will allow up to six -: :_option_argument options??? You don't have a : choice in your case statement and you don't need to specify an option more than once in that operand even if more than one of those options are allowed.

I would try to write code that might work for you, but I have no idea what you are trying to do. The Usage statement printed by your code when things go wrong indicate that absolutely no options are allowed.

The getopts man page on your system or the man page for your shell on your system may supply an option (or an environment variable setting) that will allow you to violate POSIX rules and allow you to process command-line arguments with options after operands by reordering your command line. My system doesn't allow that without lots of extra abnormal argument processing and I won't help you do that because I believe that any new application written to put options after operands is fundamentally broken. (The only exceptions to this are utilities like compilers and linkers that need to apply certain options to certain groups of operands and different options to different groups of operands. That does not seem to be the case for what you are trying to do.)

And, what is the use of having "options" -i optional_string1include:optional_string2 and -e optional_string3exclude:optional_string4 if you script is going to fail if both of those options are not specified on the command line? If an option has to be specified, by definition, it is not an option! Did you just forget to supply default values for these options, or are they just additional required operands and you are trying to say that the order of those operands in relation to other required operands is unspecified??? (If this is what you're saying, I personally believe this is a horrendous human factors decision.)
# 3  
Old 07-31-2016
Quote:
Originally Posted by Don Cragun
It is not! According to the standards, options must be specified on the command line BEFORE operands.

Furthermore, I have no idea why you have so many colons in the first argument passed to getopts??? Are you trying to say that you will allow up to six -: :_option_argument options??? You don't have a : choice in your case statement and you don't need to specify an option more than once in that operand even if more than one of those options are allowed.

I would try to write code that might work for you, but I have no idea what you are trying to do. The Usage statement printed by your code when things go wrong indicate that absolutely no options are allowed.

The getopts man page on your system or the man page for your shell on your system may supply an option (or an environment variable setting) that will allow you to violate POSIX rules and allow you to process command-line arguments with options after operands by reordering your command line. My system doesn't allow that without lots of extra abnormal argument processing and I won't help you do that because I believe that any new application written to put options after operands is fundamentally broken. (The only exceptions to this are utilities like compilers and linkers that need to apply certain options to certain groups of operands and different options to different groups of operands. That does not seem to be the case for what you are trying to do.)

And, what is the use of having "options" -i optional_string1include:optional_string2 and -e optional_string3exclude:optional_string4 if you script is going to fail if both of those options are not specified on the command line? If an option has to be specified, by definition, it is not an option! Did you just forget to supply default values for these options, or are they just additional required operands and you are trying to say that the order of those operands in relation to other required operands is unspecified??? (If this is what you're saying, I personally believe this is a horrendous human factors decision.)
i apologize for not being clear.

currently, there are 4 ways to run my script.

one is without any of the -i or -e options being passed to it
second is if just the -i is passed to it
third is if just the -e is pass to it
fourth is if both -i and -e are passed to the script

all im trying to do is account for those 4 scenarios using getopts.
# 4  
Old 07-31-2016
If you are trying to have 4 scenarios, why does you script run the usage macro in three of the 4 scenarios (only moving on to the final two echo commands in your script if both options are present on the command line?

Please describe what you want your script to do in these 4 scenarios. Without knowing what these 4 scenarios are, I don't see how we can guess at how to correct your script.

And, what is the format of the -i and -e option-arguments. From your code I assume that the strings include: or exclude:, respectively, must occur somewhere in the option-arguments (not necessarily at the start of those option-arguments), but why these strings are needed (rather than assumed from the option-letter) is not clear, what else is expected in those option-arguments is not clear, and whether or not some default value should be used for these option-arguments if the options are not specified on the command line is not clear.

Please also show us an actual synopsis for your utility showing the utility name, the options, and operands that are expected in the various valid manners in which your utility can be invoked. (For example, the string -query appears at the end of your usage statement. Is that an indication that there are 4 more options (-q, -u, -r, and -y as well as a -e without an option-argument), or is it another mandatory string that is supposed to appear as the final operand to your utility?

You seem to have several operands that are required to be constant pathnames. Why does a user have to type in a constant pathname when your script could supply it automatically without the user having to type it in every time your script is invoked?
This User Gave Thanks to Don Cragun For This Post:
# 5  
Old 07-31-2016
Hi.
Quote:
Originally Posted by SkySmart
... i want to be able to specify the "-i" or "-e" or any additional arguments, wherever i want on the command line. how is this possible?
i need this to be portable as i'll be using it across many platforms. ...
The *nix body of code suggests that options should come before arguments. So I am not surprised that you will not find support in standard utilities that goes beyond that.

However, there are other codes that do support mixed arguments and options. For example:
1) code getopt from util-linux at kernel.org, possibly in a repository (it was in Debian, from which I installed it): util-linux - Wikipedia, the free encyclopedia
A stand-alone version of source is available at:
Getopt | frodo.looijaard.name
Because ultimately it's a binary:
Code:
$ file /usr/bin/getopt
/usr/bin/getopt: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
 dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, 
BuildID[sha1]=31f6f91c2197e0da68251db8ee918c8c56c250d4, stripped

it should be able to be compiled anyplace there is a building environment.

2) A Google code, shFlags:
Quote:
shFlags is a Unix shell library to simplify the handling of command-line flags.

_Tested Operating Systems_

Linux ([The leading OS for PC, tablet, phone and cloud | Ubuntu Ubuntu] 8.04 LTS, 10.04 LTS, 12.04 LTS)
[OSĀ*X - Overview - Apple Mac OS X] 10.8
[Oracle and Sun Microsystems | Strategic Acquisitions | Oracle Solaris] 9, 10, !OpenSolaris 2009.06

Tested Shells

Bourne Shell (`sh`)
[http://www.gnu.org/software/bash/ BASH] - GNU Bourne Again SHell (`bash`)
[http://gondor.apana.org.au/~herbert/dash/ DASH] (`dash`)
[http://www.kornshell.com/ Korn Shell] (`ksh`)
[http://web.cs.mun.ca/~michael/pdksh/ pdksh] - the Public Domain Korn Shell (`pdksh`)
[http://www.zsh.org/ Zsh] (`zsh`)

Development and testing of shFlags was done by Kate Ward. More products for Unix shell scripts can be found at http://forestent.com/.
excerpt from https://github.com/kward/shflags/wiki/ProjectInfo
code at https://github.com/kward/shflags
documentation at: https://github.com/kward/shflags/wiki/Documentation12x

That seems like a lot of extra work just to allow the mix of options and arguments -- probably too much for me in most instances -- but if you are sufficiently motivated, it can be done. In essence, you are rolling your own command-line processing with the support from those 2 projects (probably among many others about which I do not know).

Good luck ... cheers, drl

Last edited by drl; 07-31-2016 at 10:18 AM..
This User Gave Thanks to drl For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

problem with getopts

Hi, I have written a script to take command line arguments using geopts.This is the code. #!/bin/sh # The usage of this script. usage="Usage is $0" usage="$usage " usage="$usage " usage="$usage " # Use the getopt utility to set up the command line flags. set -- `/usr/bin/getopt... (4 Replies)
Discussion started by: arijitsaha
4 Replies

2. Shell Programming and Scripting

Identify function image magick problem - perl

Hi, I got some error when I try to write content from file store into array then for each word that separate by space use identify function to display image information.here is my code #!/usr/bin/perl -w open(FILE,'transfer_file_perl.txt') or die "$!"; my $line = <FILE>;#because it is one... (2 Replies)
Discussion started by: guidely
2 Replies

3. Shell Programming and Scripting

getopts - optional and problem to display help

In the below code while getopts :rfw:d:s:a: options do case "$options" in r) echo reverse;; f) echo forward;; w) window=$OPTARG;; d) duration=$OPTARG;; s) search=$OPTARG;; a) value=$OPTARG;; *) help; exit;; esac done ... (2 Replies)
Discussion started by: Amutha
2 Replies

4. Shell Programming and Scripting

getopts problem

Hi everyone I want to know how can we pass multiple argument in getopts suppose PARAMS="abcd" while getopts ${PARMS} FLAG do case ${FLAG} in (a) (b) (c) (d) esac (6 Replies)
Discussion started by: aishsimplesweet
6 Replies

5. Shell Programming and Scripting

getopts problem

How do I get the getopts command to display whats written at my help option if no option is types in? For example, myscript.sh -h will bring up my help option, however, I also want myscript.sh to do the same! #!/bin/bash while getopts :abh opt do case "$opt" in... (2 Replies)
Discussion started by: linuxkid
2 Replies

6. HP-UX

using getopts

Is there a restriction on levels of using 'getopts' ? I have several scripts, each of which requires an option as the first parameter . If I call one prg separately it works fine, but when one prg calls another prg and passes the option on the called prg, then the called prg seems not to process... (3 Replies)
Discussion started by: vslewis
3 Replies

7. UNIX for Advanced & Expert Users

getopts problem

i was going through the man page of getopts this particular section is not clear to me can anyone please clarify in a little detail so that i can understand the concept MANPAGE:: Since getopts affects the current shell execution environ- ment, it is generally provided as a... (7 Replies)
Discussion started by: mobydick
7 Replies

8. Shell Programming and Scripting

problem with getopts

Hi, I am a new member to unix.com. Actually I am facing a problem with getopts. In my script i have used getopts to parse the parameters. when i use the script as shown below its working fine: find_status -p all ### where find_status is a script name. But even if I pass more than one... (3 Replies)
Discussion started by: pvamsikr
3 Replies

9. Shell Programming and Scripting

Problem in getopts

while getopts l:f:s:o:h: c do case $c in l) tail -${OPTARG} /etc/passwd exit 2;; f) head -${OPTARG} /etc/passwd exit 3;; s) grep ${OPTARG} /etc/passwd | cut -d: -f7 exit 4;; o) OARG=$OPTARG exit 5;; h) ... (3 Replies)
Discussion started by: nadman123
3 Replies

10. Shell Programming and Scripting

Problem with getopts

I need to parse parameters but the arguments could be NULL,example: > cat getopts.sh while getopts "a:b:" opt 2>/dev/null do case "${opt}" in a) echo "A:${OPTARG}" ;; b) echo "B:${OPTARG}" ;; *) exit 1 ;; esac done > getopts.sh -a TEST1 -b TEST2... (5 Replies)
Discussion started by: Klashxx
5 Replies
Login or Register to Ask a Question