Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

bash - Optional option argument with getopts

while getopts "hd:R:" arg; do
  case $arg in
    h)
      echo "usgae" 
      ;;
    d)
      dir=$OPTARG
      ;;
    R)
      if [[ $OPTARG =~ ^[0-9]+$ ]];then
        level=$OPTARG
      else
        level=1
      fi
      ;;
    ?)
      echo "WRONG" >&2
      ;;
  esac
done
  • level refers to parameter of -R, dir refers to parameters of -d

  • when I input ./count.sh -R 1 -d test/ it works rightly

  • when I input ./count.sh -d test/ -R 1 it works rightly

  • but I want to make it work when I input ./count.sh -d test/ -R or ./count.sh -R -d test/

This means that I want -R has a default value and the sequence of command could be more flexible.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Wrong. Actually getopts does support optional arguments! From the bash man page:

If  a  required  argument is not found, and getopts is not silent, 
a question mark (?) is placed in name, OPTARG is unset, and a diagnostic
message is printed.  If getopts is silent, then a colon (:) is placed in name 
and OPTARG is set to the option character found.

When the man page says "silent" it means silent error reporting. To enable it, the first character of optstring needs to be a colon:

while getopts ":hd:R:" arg; do
    # ...rest of iverson's loop should work as posted 
done

Since Bash's getopt does not recognize -- to end the options list, it may not work when -R is the last option, followed by some path argument.

P.S.: Traditionally, getopt.c uses two colons (::) to specify an optional argument. However, the version used by Bash doesn't.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...