7

Bash: Parse Options And Non-Options With Getopts

 2 years ago
source link: https://blog.jakubholy.net/2013/01/09/bash-parse-options-and-non-options-with-getopts/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Bash: Parse Options And Non-Options With Getopts

January 9, 2013
Parsing script or function options and non-option arguments is easy in Bash with getopts but there are some catches, such as the need to reset OPTIND. We will se how to do it using getopts, shift, and case.

The code below will parse the function arguments and remove them so that $1 will refer to the first non-option argument (i.e. not starting with -). You would invoke it f.ex. as  latest_recur -x Hello -a '*.txt'.

# Find the latest files under the current dir, recursively; options:
# -a list all, not only 30 latest
#  - pattern passed to find's -name; ex.: "*.log.processed"
function latest_recur {
   local show_all=
   OPTIND=1
   while getopts "ax:" opt; do
      case $opt in
         a) show_all=yes ;;
         x) echo "You said: $OPTARG" ;;
         \?) echo "Invalid option: -$OPTARG" >&2; return 1;;
     esac
   done
   shift $((OPTIND-1))

if [ -z "$1" ]; then NAME_ARG=""; else NAME_ARG="-name $1"; fi find -type f $NAME_ARG | xargs --no-run-if-empty stat --format '%Y :%y %n' | sort -nr | if [ -z "$show_all" ]; then head -n 30 -; else cat -; fi }
  • #5, #9 the variable used to store the flag must be defined/reset first
  • #6 OPTIND is a global variable pointing to the next argument that getopts should parse; you must reset it manually (otherwise the next call to the function will ignore its arguments)
  • #7 getopts parses one by one all the supported options (a, x here) and stores them into $opt;
  • #10, #11 the value passed to the option (Hello, *.txt) is stored into the variable OPTARG
  • #14 we must manually shift away the processed option arguments so that the first non-option argument ('*.txt') will become argument number 1 as you can see at #16; OPTIND is set by getopts
Getopts can do quite a lot. It supports short options with or without arguments such as "-lht", "-l -h -t", "-l -I '*.swp'". It can also report/ignore unknown arguments etc., see its brief documentation and this small getopts tutorial. Briefly said, getopts takes opstring and varname; opstring is a list of letters optionally followed by ':' to indicate that that flag requires a value; varname is the name of the variable to store the flag name into. If you put : in front of the opstring (":ax:") then it will not complain about unknown options or missing arguments for options that require them.

Are you benefitting from my writing? Consider buying me a coffee or supporting my work via GitHub Sponsors. Thank you! You can also book me for a mentoring / pair-programming session via Codementor or (cheaper) email.

Allow me to write to you!

Let's get in touch! I will occasionally send you a short email with a few links to interesting stuff I found and with summaries of my new blog posts. Max 1-2 emails per month. I read and answer to all replies.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK