Bug 5744

Summary: getopt not recognized long options
Product: Busybox Reporter: Evgheni <aidjek>
Component: Standard ComplianceAssignee: unassigned
Status: RESOLVED FIXED    
Severity: minor CC: aidjek, busybox-cvs
Priority: P5    
Version: unspecified   
Target Milestone: ---   
Hardware: Other   
OS: Linux   
Host: Target:
Build:
Attachments: .config_busybox_1.20.2

Description Evgheni 2012-11-30 07:45:56 UTC
Created attachment 4664 [details]
.config_busybox_1.20.2

The have simple script which use getopt for handling input arguments
#!/bin/sh

aflag=no
bflag=no
cargument=none

# options may be followed by one colon to indicate they have a required argument
if ! options=$(/mnt/db/updates/getopt -o abc: -l along,blong,clong: -- "$@")
then
    # something went wrong, getopt will put out an error message for us
    exit 1
fi

set -- $options

while [ $# -gt 0 ]
do
    case $1 in
    -a|--along) aflag="yes" ;;
    -b|--blong) bflag="yes" ;;
    # for options with required arguments, an additional shift is required
    -c|--clong) cargument="$2" ; shift;;
    (--) shift; break;;
    (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
    (*) break;;
    esac
    shift
done

During execution of this script the have following error:

#!/bin/sh

aflag=no
+ aflag=no
bflag=no
+ bflag=no
cargument=none
+ cargument=none

# options may be followed by one colon to indicate they have a required argument
if ! options=$(getopt -o abc: -l along,blong,clong: -- "$@")
then
    # something went wrong, getopt will put out an error message for us
    exit 1
fi
+ getopt -o abc: -l along,blong,clong: --
getopt: invalid option -- l
BusyBox v1.20.2 (2012-07-18 09:31:57 EEST) multi-call binary.

Usage: getopt [OPTIONS] [--] OPTSTRING PARAMS

        -a,--alternative                Allow long options starting with single -
        -l,--longoptions=LOPT[,...]     Long options to be recognized
        -n,--name=PROGNAME              The name under which errors are reported
        -o,--options=OPTSTRING          Short options to be recognized
        -q,--quiet                      Disable error reporting by getopt(3)
        -Q,--quiet-output               No normal output
        -s,--shell=SHELL                Set shell quoting conventions
        -T,--test                       Test for getopt(1) version
        -u,--unquoted                   Don't quote the output

Example:

O=`getopt -l bb: -- ab:c:: "$@"` || exit 1
eval set -- "$O"
while true; do
        case "$1" in
        -a)     echo A; shift;;
        -b|--bb) echo "B:'$2'"; shift 2;;
        -c)     case "$2" in
                "")     echo C; shift 2;;
                *)      echo "C:'$2'"; shift 2;;
                esac;;
        --)     shift; break;;
        *)      echo Error; exit 1;;
        esac
done

+ options=
+ exit 1

getopt -V
getopt: invalid option -- V
BusyBox v1.20.2 (2012-07-18 09:31:57 EEST) multi-call binary.

Usage: getopt [OPTIONS] [--] OPTSTRING PARAMS

        -a,--alternative                Allow long options starting with single -
        -l,--longoptions=LOPT[,...]     Long options to be recognized
        -n,--name=PROGNAME              The name under which errors are reported
        -o,--options=OPTSTRING          Short options to be recognized
        -q,--quiet                      Disable error reporting by getopt(3)
        -Q,--quiet-output               No normal output
        -s,--shell=SHELL                Set shell quoting conventions
        -T,--test                       Test for getopt(1) version
        -u,--unquoted                   Don't quote the output

Example:

O=`getopt -l bb: -- ab:c:: "$@"` || exit 1
eval set -- "$O"
while true; do
        case "$1" in
        -a)     echo A; shift;;
        -b|--bb) echo "B:'$2'"; shift 2;;
        -c)     case "$2" in
                "")     echo C; shift 2;;
                *)      echo "C:'$2'"; shift 2;;
                esac;;
        --)     shift; break;;
        *)      echo Error; exit 1;;
        esac
done

Trying to execute script, representated in example part:

#!/bin/sh

O=`getopt -l bb: -- ab:c:: "$@"` || exit 1
+ getopt -l bb: -- ab:c::
getopt: invalid option -- l
BusyBox v1.20.2 (2012-07-18 09:31:57 EEST) multi-call binary.

Usage: getopt [OPTIONS] [--] OPTSTRING PARAMS

        -a,--alternative                Allow long options starting with single -
        -l,--longoptions=LOPT[,...]     Long options to be recognized
        -n,--name=PROGNAME              The name under which errors are reported
        -o,--options=OPTSTRING          Short options to be recognized
        -q,--quiet                      Disable error reporting by getopt(3)
        -Q,--quiet-output               No normal output
        -s,--shell=SHELL                Set shell quoting conventions
        -T,--test                       Test for getopt(1) version
        -u,--unquoted                   Don't quote the output

Example:

O=`getopt -l bb: -- ab:c:: "$@"` || exit 1
eval set -- "$O"
while true; do
        case "$1" in
        -a)     echo A; shift;;
        -b|--bb) echo "B:'$2'"; shift 2;;
        -c)     case "$2" in
                "")     echo C; shift 2;;
                *)      echo "C:'$2'"; shift 2;;
                esac;;
        --)     shift; break;;
        *)      echo Error; exit 1;;
        esac
done

+ O=
+ exit 1

As we can see getopt don't work with several it's options.

If have another getopt, compiled from this sources
http://ftp.de.debian.org/debian/pool/main/u/util-linux/util-linux_2.17.2.orig.tar.gz

/mnt/db/updates/getopt --help
Usage: getopt optstring parameters
       getopt [options] [--] optstring parameters
       getopt [options] -o|--options optstring [options] [--]
              parameters
  -a, --alternative            Allow long options starting with single -
  -h, --help                   This small usage guide
  -l, --longoptions=longopts   Long options to be recognized
  -n, --name=progname          The name under which errors are reported
  -o, --options=optstring      Short options to be recognized
  -q, --quiet                  Disable error reporting by getopt(3)
  -Q, --quiet-output           No normal output
  -s, --shell=shell            Set shell quoting conventions
  -T, --test                   Test for getopt(1) version
  -u, --unqote                 Do not quote the output
  -V, --version                Output version information

all is fine

#!/bin/sh

O=`/mnt/db/updates/getopt -l bb: -- ab:c:: "$@"` || exit 1
+ /mnt/db/updates/getopt -l bb: -- ab:c::
+ O= --
eval set -- "$O"
+ eval set --  --
+ set -- --
while true; do
        case "$1" in
        -a)     echo A; shift;;
        -b|--bb) echo "B:'$2'"; shift 2;;
        -c)     case "$2" in
                "")     echo C; shift 2;;
                *)      echo "C:'$2'"; shift 2;;
                esac;;
        --)     shift; break;;
        *)      echo Error; exit 1;;
        esac
done+ true
+ shift
+ break


Config of busybox is attached
Comment 1 Denys Vlasenko 2013-01-24 10:30:51 UTC
You have FEATURE_GETOPT_LONG disabled in your .config. -l option need it enabled.

I am fixing help text to not show -l if it is disabled.
Comment 2 Evgheni 2013-01-24 11:05:40 UTC
(In reply to comment #1)
> You have FEATURE_GETOPT_LONG disabled in your .config. -l option need it
> enabled.
> 
> I am fixing help text to not show -l if it is disabled.

A lot of thanks, Denis. Will check this features on our next release update.