How to catch optioned and non optioned arguments correctly?
Solution 1
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.
Solution 2
After capturing your options
shift $OPTIND
if [ $# -eq 1 ]; then
some_str="$1"
else
echo "Error: missing argument" >&2
fi
Related videos on Youtube
chanchal1987
Now working in a Unix platform. Wanna get & share knowledge of Unix from/with others... Badge:
Updated on September 17, 2022Comments
-
chanchal1987 over 1 year
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?-
mattdm about 13 yearsWhen 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.
-
Shawn J. Goff about 13 yearsPosix 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.
-
Angel Todorov about 13 yearsPerl's
Getopt::Long
will extract the options and leave the non-option arguments in @ARGV. -
xenoterracide about 13 yearsjust 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.
-
chanchal1987 about 13 yearsFor
./abc.ksh "some_string" -a "sample text"
, it will not work. -
Angel Todorov about 13 yearsWell 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."