Skip to main content
deleted 315 characters in body
Source Link
Mihir Luthra
  • 6.9k
  • 3
  • 19
  • 45

I wanted to share what I made for parsing options. Some of my needs were not fulfilled (like suboption management, var args, optional args etc.) by the answers here so I had to come up with this: https://github.com/MihirLuthra/bash_option_parser

This supports:

  • Suboption parsing
  • Alias names for options
  • Optional args
  • Variable args
  • Printing usage and errors
fruit <fruit-name> ...
   [-e|—-eat|—-chew]
   [-c|--cut <how> <why>]
   <command> [<args>] 
fruit <fruit-name> ...
   [-e|—-eat|—-chew]
   [-c|--cut <how> <why>]
   <command> [<args>] 
retval=$?

if [ $retval -ne 0 ]; then
    # this will manage error messages if
    # insufficient or extra args are supplied

    option_parser_error_msg "$retval" 

 'OPTIONS'   # This will print the usage
    print_usage 'fruit'
    exit 1
fi
if [ -n "${OPTIONS[-c]}" ]
then
    echo "-c was passed"

    # args can be accessed in a 2D-array-like format
    echo "Arg1 to -c = ${ARGS[-c,0]}"
    echo "Arg2 to -c = ${ARGS[-c,1]}"

fi

For a suboption, like apple whose usage looks like:

fruit apple ...
   [—-eat-apple|—-chew-apple]
   [-p|—-peel <how>] 

We can check if it was passed and parse it as follows:

if [ -n "${OPTION[apple]}" ]
then
    shift_count=${OPTION[apple]}

    parse_options_detailed \
        ',' 'OPTIONS_APPLE' 'ARG_CNT_APPLE' 'ARGS_APPLE' \
        "$shift_cnt" ';' '--' 'error_opt'                \
                                                         \
        'apple'                         '...'            \
        '—-eat-apple' , '—-chew-apple'  '0'              \
        '-p'          , '—-peel'        '1'              \
        ';' \
        "$@"
fi

Suboption parsing iscan also be done by passing $shift_count to parse_options_detailed which makes it start parsing after shifting args to reach args of suboption. It is demonstrated in this example.

I wanted to share what I made for parsing options. Some of my needs were not fulfilled (like suboption management, var args, optional args etc.) by the answers here so I had to come up with this: https://github.com/MihirLuthra/bash_option_parser

fruit <fruit-name> ...
   [-e|—-eat|—-chew]
   [-c|--cut <how> <why>]
   <command> [<args>] 
retval=$?

if [ $retval -ne 0 ]; then
    option_parser_error_msg "$retval" 'OPTIONS'
    exit 1
fi
if [ -n "${OPTIONS[-c]}" ]
then
    echo "-c was passed"

    # args can be accessed in a 2D-array-like format
    echo "Arg1 to -c = ${ARGS[-c,0]}"
    echo "Arg2 to -c = ${ARGS[-c,1]}"

fi

For a suboption, like apple whose usage looks like:

fruit apple ...
   [—-eat-apple|—-chew-apple]
   [-p|—-peel <how>] 

We can check if it was passed and parse it as follows:

if [ -n "${OPTION[apple]}" ]
then
    shift_count=${OPTION[apple]}

    parse_options_detailed \
        ',' 'OPTIONS_APPLE' 'ARG_CNT_APPLE' 'ARGS_APPLE' \
        "$shift_cnt" ';' '--' 'error_opt'                \
                                                         \
        'apple'                         '...'            \
        '—-eat-apple' , '—-chew-apple'  '0'              \
        '-p'          , '—-peel'        '1'              \
        ';' \
        "$@"
fi

Suboption parsing is done by passing $shift_count to parse_options_detailed which makes it start parsing after shifting args to reach args of suboption.

I wanted to share what I made for parsing options. Some of my needs were not fulfilled by the answers here so I had to come up with this: https://github.com/MihirLuthra/bash_option_parser

This supports:

  • Suboption parsing
  • Alias names for options
  • Optional args
  • Variable args
  • Printing usage and errors
fruit <fruit-name> ...
   [-e|—-eat|—-chew]
   [-c|--cut <how> <why>]
   <command> [<args>] 
retval=$?

if [ $retval -ne 0 ]; then
    # this will manage error messages if
    # insufficient or extra args are supplied

    option_parser_error_msg "$retval" 

    # This will print the usage
    print_usage 'fruit'
    exit 1
fi
if [ -n "${OPTIONS[-c]}" ]
then
    echo "-c was passed"

    # args can be accessed in a 2D-array-like format
    echo "Arg1 to -c = ${ARGS[-c,0]}"
    echo "Arg2 to -c = ${ARGS[-c,1]}"

fi

Suboption parsing can also be done by passing $shift_count to parse_options_detailed which makes it start parsing after shifting args to reach args of suboption. It is demonstrated in this example.

deleted 164 characters in body
Source Link
Mihir Luthra
  • 6.9k
  • 3
  • 19
  • 45
fruit <fruit-name> ...
   [-e|—-eat|—-chew]
   [-c|--cut <how> <why>]
   <command> [<args>] 

-e takes no args
-c takes two args i.e. how to cut and why to cut
fruit itself takes at least one argument.
<command> is for suboptions like apple, orange etc. (similar to git which has suboptions commit, push etc. )

source ./option_parser

parse_options \
    ',' 'OPTIONS' 'ARG_CNT' 'ARGS' 'self' '0' ';' '--'  \
                                                        \
    '-e'    , '—-eat' , '—-chew'  '0'                   \
    '-c'    , '—-cut' ,           '1 1'                 \
    'apple'                       'S'                   \
    'orange'                      'S'                   \
                                                        \
    ';' "$@"
parse_options \
    'fruit'                         '1 ...'  \
    '-e'     , '--eat' , '--chew'   '0'      \
    '-c'     , '--cut'              '1 1'    \
    'apple'                         'S'      \
    'orange'                        'S'      \
    ';' \
    "$@"
if [ -n "${OPTION[apple]}" ]
then
    shift_count=${OPTION[apple]}

    parse_optionsparse_options_detailed \
        ',' 'OPTIONS_apple''OPTIONS_APPLE' 'ARG_CNT_apple''ARG_CNT_APPLE' 'ARGS_apple''ARGS_APPLE' \
   \
    'self' "$shift_count""$shift_cnt" ';' '--'      'error_opt'                \
                                                         \
    '—-eat-apple' , '—-chew-apple'  '0''apple'                 \
    '-p'    '...'      , '—-peel'     \
   '1'     '—-eat-apple' , '—-chew-apple'  '0'        \
      \
        '-p'          , '—-peel'        '1'              \
        ';' \
    ';'    "$@"
 
fi

Suboption parsing is done by passing $shift_count to parse_optionsparse_options_detailed which makes it start parsing after shifting args to reach args of suboption.

fruit ...
   [-e|—-eat|—-chew]
   [-c|--cut <how> <why>]
   <command> [<args>] 

-e takes no args
-c takes two args i.e. how to cut and why to cut
<command> is for suboptions like apple, orange etc. (similar to git which has suboptions commit, push etc. )

source ./option_parser

parse_options \
    ',' 'OPTIONS' 'ARG_CNT' 'ARGS' 'self' '0' ';' '--'  \
                                                        \
    '-e'    , '—-eat' , '—-chew'  '0'                   \
    '-c'    , '—-cut' ,           '1 1'                 \
    'apple'                       'S'                   \
    'orange'                      'S'                   \
                                                        \
    ';' "$@"
if [ -n "${OPTION[apple]}" ]
then
    shift_count=${OPTION[apple]}

    parse_options \
    ',' 'OPTIONS_apple' 'ARG_CNT_apple' 'ARGS_apple'    \
    'self' "$shift_count" ';' '--'                      \
                                                        \
    '—-eat-apple' , '—-chew-apple'  '0'                 \
    '-p'          , '—-peel'        '1'                 \
                                                        \
    ';' "$@"
 
fi

Suboption parsing is done by passing $shift_count to parse_options which makes it start parsing after shifting args to reach args of suboption.

fruit <fruit-name> ...
   [-e|—-eat|—-chew]
   [-c|--cut <how> <why>]
   <command> [<args>] 

-e takes no args
-c takes two args i.e. how to cut and why to cut
fruit itself takes at least one argument.
<command> is for suboptions like apple, orange etc. (similar to git which has suboptions commit, push etc. )

parse_options \
    'fruit'                         '1 ...'  \
    '-e'     , '--eat' , '--chew'   '0'      \
    '-c'     , '--cut'              '1 1'    \
    'apple'                         'S'      \
    'orange'                        'S'      \
    ';' \
    "$@"
if [ -n "${OPTION[apple]}" ]
then
    shift_count=${OPTION[apple]}

    parse_options_detailed \
        ',' 'OPTIONS_APPLE' 'ARG_CNT_APPLE' 'ARGS_APPLE' \
        "$shift_cnt" ';' '--' 'error_opt'                \
                                                         \
        'apple'                         '...'            \
        '—-eat-apple' , '—-chew-apple'  '0'              \
        '-p'          , '—-peel'        '1'              \
        ';' \
        "$@"
fi

Suboption parsing is done by passing $shift_count to parse_options_detailed which makes it start parsing after shifting args to reach args of suboption.

Source Link
Mihir Luthra
  • 6.9k
  • 3
  • 19
  • 45

I wanted to share what I made for parsing options. Some of my needs were not fulfilled (like suboption management, var args, optional args etc.) by the answers here so I had to come up with this: https://github.com/MihirLuthra/bash_option_parser

Let's say we have a command named fruit with usage as follows:

fruit ...
   [-e|—-eat|—-chew]
   [-c|--cut <how> <why>]
   <command> [<args>] 

-e takes no args
-c takes two args i.e. how to cut and why to cut
<command> is for suboptions like apple, orange etc. (similar to git which has suboptions commit, push etc. )

So to parse it:

source ./option_parser

parse_options \
    ',' 'OPTIONS' 'ARG_CNT' 'ARGS' 'self' '0' ';' '--'  \
                                                        \
    '-e'    , '—-eat' , '—-chew'  '0'                   \
    '-c'    , '—-cut' ,           '1 1'                 \
    'apple'                       'S'                   \
    'orange'                      'S'                   \
                                                        \
    ';' "$@"

Now if there was any usage error, it can be printed using option_parser_error_msg as follows:

retval=$?

if [ $retval -ne 0 ]; then
    option_parser_error_msg "$retval" 'OPTIONS'
    exit 1
fi

To check now if some options was passed,

if [ -n "${OPTIONS[-c]}" ]
then
    echo "-c was passed"

    # args can be accessed in a 2D-array-like format
    echo "Arg1 to -c = ${ARGS[-c,0]}"
    echo "Arg2 to -c = ${ARGS[-c,1]}"

fi

For a suboption, like apple whose usage looks like:

fruit apple ...
   [—-eat-apple|—-chew-apple]
   [-p|—-peel <how>] 

We can check if it was passed and parse it as follows:

if [ -n "${OPTION[apple]}" ]
then
    shift_count=${OPTION[apple]}

    parse_options \
    ',' 'OPTIONS_apple' 'ARG_CNT_apple' 'ARGS_apple'    \
    'self' "$shift_count" ';' '--'                      \
                                                        \
    '—-eat-apple' , '—-chew-apple'  '0'                 \
    '-p'          , '—-peel'        '1'                 \
                                                        \
    ';' "$@"

fi

Suboption parsing is done by passing $shift_count to parse_options which makes it start parsing after shifting args to reach args of suboption.

A detailed description is provided in the readme and examples in the repository.