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, 2011 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. Mar 8, 2011 at 13:51
  • Perl's Getopt::Long will extract the options and leave the non-option arguments in @ARGV. Mar 8, 2011 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. Mar 9, 2011 at 13:06

2 Answers 2


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. Mar 8, 2011 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." Mar 8, 2011 at 13:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .