Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to write a shell script which will take some arguments with some options and print that arguments. Suppose the name of that script is abc.ksh. Usage of that script is -
./abc.ksh -[a <arg>|b <arg>|c|d] <some_string>
Now I write a shell script which will take options and arguments

#!/bin/ksh

# Default Values
vara=","
varb=false
varbname=""
varc=false

# Scanning inputs
while getopts :a:b:cd option
do
        case $option in
                a) vara=$OPTARG;;
                   #shift $((OPTIND-1));;
                b) varb=true
                   varbname=$OPTARG;;
                   #shift $((OPTIND-1));;
                c) varc=true;;
                   #shift $((OPTIND-1));;
                d) echo "Usage $0 \-[a|b|c|d] <filename>"
                   exit 0;;
                \?) echo "Invalid option -$OPTARG. Please run '$0 -h' for help"
                    exit 1;;
                :) echo "Option -$OPTARG requires an argument. Please run '$0 -d' for help"
                   exit 1;;
esac
done

print "Args: $* \nvara: $vara \noptfile: $varb \nvarbname: $varbname \nvarc: $varc"

Examples of Correct Inputs:

  • ./abc.ksh -a "sample text" "some_string"
  • ./abc.ksh "some_string" -a "sample text"
  • ./abc.ksh -asample\ text some_string
  • etc...

some_string input is not catch in my script. How can I catch that?

share|improve this question
2  
When you're getting to the level of complication where you're asking yourself this sort of question, I think it's time to shift to asking "should I be using a full scripting language instead"? Python, perl, whatever — they all have pre-existing modules for handing this gracefully and transparently. –  mattdm Mar 8 '11 at 12:59
3  
Posix shell is a very capable scripting language, very capable of doing what he is asking in this question. This is not at all a complicated thing. –  Shawn J. Goff Mar 8 '11 at 13:51
    
Perl's Getopt::Long will extract the options and leave the non-option arguments in @ARGV. –  glenn jackman Mar 8 '11 at 14:44
    
just use getopt ? man getopt I've only used getopt in C so I can't really say exactly what the code should look like, but it seems like better than implementing getopt yourself. –  xenoterracide Mar 9 '11 at 13:06

2 Answers 2

up vote 5 down vote accepted

It is typical for programs to force the "some_string" part to be the last argument so that .abc.ksh "some_string" -a "sample text" is an error. If you do this, then after parsing the options, $OPTIND holds the index to the last argument (the "some_string" part).

If that is not acceptable, then you can check at the beginning (before you enter the while to see if there is a non-prefixed argument. This will let you have "some_string" at the beginning and at the end. If you needed to have it in the middle, you could either not use getopts or you could have two sets of getopts. When the first one errors out, it could be due to the non-prefixed argument; get it and start a new getopts to get the remaining args. Or you can skip getopts all together and roll your own solution.

share|improve this answer

After capturing your options

shift $OPTIND
if [ $# -eq 1 ]; then
  some_str="$1"
else
  echo "Error: missing argument" >&2
fi
share|improve this answer
    
For ./abc.ksh "some_string" -a "sample text", it will not work. –  chanchal1987 Mar 8 '11 at 12:18
    
Well for getopts, you're constrained by the tool: "Any of the following identifies the end of options: the special option --, finding an argument that does not begin with a -, or encountering an error." –  glenn jackman Mar 8 '11 at 13:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.