How to avoid preceding whitespace using getopts?

I wish to avoid preceding white space for getopts variables.

Below is my test.sh script:

while getopts ":a:b:c:" opt
do
   case "$opt" in
      a ) Region=$OPTARG;;
      b)Environment=$OPTARG;;
      c ) Location="$OPTARG";;
   esac
done

echo "$Region"
echo "$Location"
echo "This_is_fine"
echo "$Environment"

Output:

As you can see there is a preceding whitespace in the output for Ëurope, PRODUCTION and INDIA.

Is it possicle to get the variables not have any whitespaces and avoid usig trim functionality of shell script.

I m using both bash and non-bash shell.

We can't see as you are using Quote instead of Code tags.

Just dropping the single quotes gets you there:

./test.sh -a Europe -b INDIA -c PRODUCTION
Europe
PRODUCTION
This_is_fine
INDIA

What if the incoming request to the test script is from a tool call Jenkins and the parameters could be multiline strings or comma separated which enforces us to have quotes around each argument. Any suggestions on such a case?

Then I would suggest posting a sample of what that looks like so we can contemplate ways to deal with it. Post what it looks like in the tool, and the actual arguments the shell receives.

OP's script is trivially solved with

set -- $*

while getopts ":a:b:c:" opt
do
   case "$opt" in
      a) Region=$OPTARG;;
      b)Environment=$OPTARG;;
      c) Location="$OPTARG";;
   esac
done

echo "$Region"
echo "$Location"
echo "This_is_fine"
echo "$Environment"

...but I suspect there's spaces you don't want to split on too, and we have no idea how to tell those apart from those spaces which you do.

OP's problem is also trivially worked around just by doing ./test.sh '-aEurope' '-bIndia' '-cProduction'

1 Like

I was looking for the solution proposed by @Corona688. However, if the last arguments '-c' does not have any value associated which is fine; the script fails and displays the helpFunction. I want -c to be optional with or without a value. So, '-c' or '-c<args>' both should work.

Changing

      ? ) helpFunction;;

to

      \? ) helpFunction;;

makes all parameters optional however, I am looking for just parameter -c to be optional (-c may not neccessarily be the last parameter)

I want the solution to work for both bash and non-bash.

I'm using a helpfunction like below:

helpFunction()
{
   echo ""
   echo "Usage: $0 -a Region -b Location -c Environment"
   echo -e "\t-a Description of what is Region"
   echo -e "\t-b Description of what is Location"
   echo -e "\t-c Description of what is Environment"
   exit 1 # Exit script after printing help
}

and

while getopts ":a:b:c:" opt
do
   case "$opt" in
      a ) Region=$OPTARG;;
      b)Environment=$OPTARG;;
      c ) Location="$OPTARG";;
      ? ) helpFunction;;
   esac
done

echo "$Region"
echo "$Location"
echo "This_is_fine"
echo "$Environment"

I don't think the builtin getopts allows for optional arguments, unfortunately. If you are on a GNU system and have access to the external GNU version of getopt you can have optional arguments to one or more of your options, but I believe getopt is considered deprecated. Its usage is also inconsistent with that of getopts.

Andrew

Hi.

In solving problems, I find it most useful to search for solutions before inventing my own. I keep a list of notes and sources for command-line-processing, posted below. You may want to consider items 4 and 5 below, neither of which is trivial to use. However, because of your requirement to run on all shells, I think you will probably have to do your own processing with the lowest common denominator features of the Bourne shell -- no additional features such as found on bash , ksh , zsh [/ICODE], etc. Of course, you could choose the most-feature-rich shell, possibly zsh or pwsh , and write simple driver scripts for the other shells, provided you can install zsh / pwsh on all systems that you need. The perl modules have extensive support for command-line options, so one could write a perl code that processed arguments, and then have the perl code call a vanilla shell script with simple arguments.

Good luck, I'd be interested in how you solve this ... cheers, drl

       
Process command-line (CLI) options, arguments

        1) getopts, builtin, bash, ksh, zsh
           http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options
           Also, search for option processing, including:
           http://mywiki.wooledge.org/ComplexOptionParsing

        2) perl: many, including libgetopt-euclid-perl, which
           creates man page, help automatically

        3) getopt, enhanced getopts, part of the util-linux, allows GNU "--"
           Examples: /usr/share/doc/util-linux/examples, 2016.03.27

        4) argp.sh, wrapper for getopt, creates man and help (text, XML), etc.
           Allows mixed options and arguments.
           Compiled argp.c -> argp for faster execution.
           https://sourceforge.net/projects/argpsh/, 2016.03.27

        5) shflags, wrapper for getopt, creates help, allow mixed options
           and arguments
           https://github.com/kward/shflags, 2016.08.01

        6) ksh getopts, enhanced, process GNU "--", creates man, help, etc.
           Examples: Learning the Korn Shell, O'Reilly, 2nd, p 380ff

        7) zsh zparseopts
           man zshmodules, part of zshutil

        8) getopts_long.sh, a getopts that supports long options à la GNU for POSIX
           shells 
           http://stchaz.free.fr/getopts_long.sh

        9) Suggested option names:
           http://www.shelldorado.com/goodcoding/cmdargs.html#flagnames