LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-28-2018, 11:56 AM   #1
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,242

Rep: Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322
What do you use to support command-line arguments for BASH scripts?


What do you use to support command-line arguments in BASH scripts?

I have a script I want to add command-line arguments to. The platforms I need it to run on are Linux and OS X.

The script-in-progress is currently here:

https://gist.github.com/duganchen/7d...311e814d090ab4

I did google, but the results were honestly kind of overwhelming.

I did find ArgBash, but honestly, I'm currently leaning towards getopts.

What does this forum recommend?
 
Old 06-28-2018, 12:00 PM   #2
Richard Cranium
Senior Member
 
Registered: Apr 2009
Location: McKinney, Texas
Distribution: Slackware64 15.0
Posts: 3,858

Rep: Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225
I use getopts.

Gah! That's what I get from posting at work.

I use getopt, which is a GNU beast.
Code:
info getopt
will provide some details.

Last edited by Richard Cranium; 06-28-2018 at 10:59 PM.
 
1 members found this post helpful.
Old 06-28-2018, 12:07 PM   #3
bassmadrigal
LQ Guru
 
Registered: Nov 2003
Location: West Jordan, UT, USA
Distribution: Slackware
Posts: 8,792

Rep: Reputation: 6656Reputation: 6656Reputation: 6656Reputation: 6656Reputation: 6656Reputation: 6656Reputation: 6656Reputation: 6656Reputation: 6656Reputation: 6656Reputation: 6656
I used getopts with a case statement.

https://github.com/bassmadrigal/scri...aster/sbgen.sh

Code:
while getopts "hfw:d:m:D:M:r:" OPTION
do
  case $OPTION in
    h ) help; exit
        ;;
    f ) FORCE=yes
        ;;
    w ) HOMEPAGE=$OPTARG
        ;;
    d ) DOWNLOAD=$OPTARG
        ;;
    m ) MD5SUM=$OPTARG
        ;;
    D ) DOWNLOAD64=$OPTARG
        ;;
    M ) MD5SUM64=$OPTARG
        ;;
    r ) REQUIRES=$OPTARG
        ;;
    * ) help; exit
        ;;
  esac
done
shift $(($OPTIND - 1))
 
1 members found this post helpful.
Old 06-28-2018, 12:28 PM   #4
jlinkels
LQ Guru
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195

Rep: Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043
I am very happy with shflags. https://github.com/kward/shflags

I think internally it uses getopts as well, but eventually you don't have to do any parsing, and just check or use the parameters as entered.

jlinkels
 
1 members found this post helpful.
Old 06-28-2018, 12:29 PM   #5
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,910

Rep: Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026
I never got on with getopts: it doesn't handle gnu style long-options, nor options with optional arguments, and from what I've read its use can also differ between implementations.

I usually just code the option parsing manually, no surprises that way.

Last edited by GazL; 06-28-2018 at 12:37 PM. Reason: expanded reasoning.
 
1 members found this post helpful.
Old 06-28-2018, 12:33 PM   #6
orbea
Senior Member
 
Registered: Feb 2015
Distribution: Slackware64-current
Posts: 1,950

Rep: Reputation: Disabled
Here is a simple portable example.

Code:
help='some help and documentation
  can go here'

while [ $# -gt 0 ]; do
  option="$1"; shift
  case "$option" in
    -- ) break ;;
    -f|--foo ) echo 'foo' ;;
    -b|--bar ) echo 'bar' ;;
    -h|--help ) echo "$help"; exit 0 ;;
    * ) echo "Unrecognized option '$option', use -h for help."; exit 1 ;;
  esac
done
 
1 members found this post helpful.
Old 06-29-2018, 08:02 AM   #7
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
Quote:
Originally Posted by GazL View Post
I never got on with getopts: it doesn't handle gnu style long-options, nor options with optional arguments, and from what I've read its use can also differ between implementations.

I usually just code the option parsing manually, no surprises that way.
coding the option parsing with case-esac and builtin getopts is hardly shorter than coding it completely manually, and does not seem to have any benefits.
nevertheless i've always been using it, just because it's built into bash.
i should try getopt some day.
 
1 members found this post helpful.
Old 06-29-2018, 09:47 AM   #8
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,910

Rep: Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026
Even when allowing for POSIX utility syntax conventions such as option combining it's really not hard to code manually, and as you say, it's not that much more long-winded or complex than the case statements employed by getopt(s).

Here's an example I wrote a few years back that follows -- to the best of my understanding -- all the POSIX guidelines, while also including support for GNU long-options. Not including the help, there are 3 example options (each in both long and short form): one with a mandatory argument, one with an optional argument and one without any argument (a basic flag). It uses no external utilities and no bashisms, just basic shell features.

Code:
#!/bin/sh

# Example of parsing command-line options/arguments.

########################################################################
usage()
{
  bs=$(tput bold) ; be=$(tput sgr0)
  cat <<-EOF

	${bs}SYNOPSIS${be}

	    options_sh [-v] [-f option_argument] [-l[option_argument]]
	        [--] [operand...]
	    options_sh [-?|--help]

	${bs}DESCRIPTION${be}

	    -?
	    --help
	        Show this usage information and exit.

	    -v | --verbose
	        Basic flag style option: takes no arguments.

	    -f <argument>
	    --file=<argument>
	        Option that requires an argument.

	    -l[n]
	    --log[=n]
	        Option that takes an optional argument (default: n=1 ).

	EOF
}

########################################################################
# Parse Option Args:

od_log="1"  # Option argument default for "LOG".

unset o_file o_log o_verbose
while [ $# -gt 0 ]
do
  case "$1" in
    --)           shift ; break ;;
    -|""|[!-]*)   break ;;
    -\?|--help)   usage ; exit 0 ;;
    --file=*)     o_file="${1#*=}" ;;
    --log)        o_log="$od_log" ;;
    --log=*)      o_log="${1#*=}" ;;
    --verbose)    o_verbose=1 ;;
    --*)          echo "unknown long option: $1" >&2 ;;
    -?*)          # short options:
                  opts="${1#-}"
                  while [ "${opts}" ]
                  do
                    nopts=${opts#?}
                    opt=${opts%${nopts}}
                    case "${opt}" in
                      v)   o_verbose=1 ;;
                      f)   if [ "${nopts}" ]; then
                             o_file="${nopts}"
                             nopts=""
                           else 
                             o_file="${2:?'-f' option expects filename argument!}"
                             shift
                           fi
                           ;;
                      l)   if [ "${nopts}" ]; then
                             o_log="${nopts}"
                             nopts=""
                           else 
                             o_log="${od_log}"
                           fi
                           ;;
                      ?)   echo "Invalid option: ${opt}" >&2 ; exit 1 ;;
                    esac
                    opts=${nopts}
                  done
                  ;;
  esac
  shift
done

########################################################################
# Validate input options/arguments:

  # Validate your input here. I find it best to keep parsing and
  # validation as two separate activities, otherwise the code
  # tends to get unwieldy.

########################################################################
# Rest of script:

[ "$o_verbose" ]  &&  echo "VERBOSE Selected"
[ "$o_file" ]     &&  echo "file: $o_file"
[ "$o_log" ]      &&  echo "LOG Selected, Value is: $o_log"


while [ $# -gt 0 ]
do
  echo "Operand: $1"
  shift
done

################################################################# End. #
Anyway, fwiw, that's my basic options boilerplate.
 
1 members found this post helpful.
Old 06-29-2018, 09:52 AM   #9
wpeckham
LQ Guru
 
Registered: Apr 2010
Location: Continental USA
Distribution: Debian, Ubuntu, RedHat, DSL, Puppy, CentOS, Knoppix, Mint-DE, Sparky, VSIDO, tinycore, Q4OS, Manjaro
Posts: 5,685

Rep: Reputation: 2713Reputation: 2713Reputation: 2713Reputation: 2713Reputation: 2713Reputation: 2713Reputation: 2713Reputation: 2713Reputation: 2713Reputation: 2713Reputation: 2713
Quote:
Originally Posted by dugan View Post
What do you use to support command-line arguments in BASH scripts?

I have a script I want to add command-line arguments to. The platforms I need it to run on are Linux and OS X.

The script-in-progress is currently here:

https://gist.github.com/duganchen/7d...311e814d090ab4

I did google, but the results were honestly kind of overwhelming.

I did find ArgBash, but honestly, I'm currently leaning towards getopts.

What does this forum recommend?
Did you examine the BASH man page sections on command line arguments? Everything you really need is there.
 
Old 06-29-2018, 10:03 PM   #10
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,242

Original Poster
Rep: Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322
Thanks all. I went with getopts.

The finished script is here:

https://github.com/duganchen/md_preview
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] C Program in Bash :Passing Newline in Command Line Arguments tuxtuxtux Programming 13 02-14-2014 03:18 AM
running shell scripts by taking command line arguments in a jsp page msoumyajit Linux - Server 1 12-21-2011 06:41 AM
[SOLVED] bash command line arguments izghitu Linux - Software 4 07-01-2010 09:23 AM
getting command line arguments in bash DEF. Programming 4 05-06-2009 11:50 AM
Bash command line arguments msreddy999 Programming 1 03-20-2009 02:56 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:45 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration