1

I already have a script that accepts only SHORT OPTIONS, and I want to extend the same script so as to pass the respective LONG OPTIONS. The existing code is given below.

while getopts :t:c: name; do   
   case name
    t) first=$OPTARG;;
    c) second=$OPTARG;;
    *) echo 'Invalid option'; break;;   
   esac 
done 
SHIFT $((OPTIND-1))

This works for short options, but how can I extend the same code to allow long option parsing?

4
  • Do the suggestions in this question help?
    – AdminBee
    Dec 12, 2019 at 12:48
  • That does not help, as it is using vendor specific enhancements on an outdated utility. getopt is outdated since ~1988 and all solutions based on the GNU vendor specific variant are non-portable.
    – schily
    Dec 12, 2019 at 13:26
  • check related answer
    – user313992
    Dec 12, 2019 at 13:53
  • Stéphane has a solution for this although it's quite --long.
    – jesse_b
    Dec 12, 2019 at 14:16

2 Answers 2

1

Given the inconsistent options available, I tend to roll my own; e.g.

SWITCH=false
VAL=default
while [ "$#" -gt 0 ] ; do
  case "${1}" in
    (-s|--switch) SWITCH=true ;;
    (-v|--value)  VAL="${2}" ; shift ;;
    (-v?*)        VAL="${1#-v}" ;;
    (--value=?*)  VAL="${1#--value=}" ;;
  esac
  shift
done
-3

This is simple, but the documentation is only in the getopt() man page from Solaris and in the getopts documentation from bosh:

http://schilytools.sourceforge.net/man/man1/bosh.1.html

scroll down to page 47 in the version from December 2019.

Let me edit your example:

while getopts ":t:(test)c:(call)" name; do   
    case $name in
    t) first=$OPTARG;;
    c) second=$OPTARG;;
    :) echo "Missing argument for -$OPTARG"; break;;
    *) echo 'Invalid option'; break;;   
    esac
done
shift $((OPTIND-1))

Note that you may need to quote arguments that contain parenthesis....

This accepts -c and --call.

Note that this only works with

  • bosh, the maintained POSIX enhanced Bourne Shell from schilytools on any OS
  • sh , the old Bourne Shell on Solaris 10
  • ksh93 on any OS

bosh in addition also supports UNIX style long options -long if optstring starts with ().

Both, ksh93 and bosh in addition support options that start with + if optstringstarts with a +. In such a case, $name contains +c instead of c, if the program has been called with +c.

BTW: Only boshsupports a method to support long options that have no adjacent short option. See bosh man page.

I am the author of schilytools.

6
  • 4
    schilytools being your project, correct? Please provide attribution if/when you're the author of a referenced tool; thank you! (I, for one, have been bitten by non-obvious usernames correlating with external projects!)
    – Jeff Schaller
    Dec 12, 2019 at 13:24
  • Well, I thought this is a well known fact...
    – schily
    Dec 12, 2019 at 13:26
  • 4
    I recognize your name and project, but I'm just one person among many thousands of registered users and ?millions? of anonymous viewers of the site. A simple "my schilytools project" or "bosh shell that I maintain" would be enough, I think.
    – Jeff Schaller
    Dec 12, 2019 at 13:33
  • I am not aware of a specific version, but I cannot say whether this feature has been copied from ksh93 to OpenSolaris or vice versa. If that feature is from OpenSolaris, you probably need a ksh93 version that is not from before 2008. BTW: are you using a ksh93 version that comes from the modified redhat sources? I just added a hint to quoting...
    – schily
    Dec 12, 2019 at 13:44
  • @ilkkachu It works with the ksh93 from debian 10 (93u+ 2012-08-01). It also works with the current "ksh2020" development of ksh93.
    – user313992
    Dec 12, 2019 at 14:01

You must log in to answer this question.