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


# Default Values

# Scanning inputs
while getopts :a:b:cd option
        case $option in
                a) vara=$OPTARG;;
                   #shift $((OPTIND-1));;
                b) varb=true
                   #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;;

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?

  • 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

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.


After capturing your options

shift $OPTIND
if [ $# -eq 1 ]; then
  echo "Error: missing argument" >&2
  • 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

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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