使用getopt
为什么选择 getopt?
解析详细的命令行参数以避免混淆并阐明我们正在解析的选项,以便命令的读者可以理解正在发生的事情。
什么是 getopt?
getopt 用于分解(解析)命令行中的选项,以便于 shell 程序解析,并检查合法选项。它使用 GNU getopt(3) 例程来执行此操作。
getopt 可以有以下几种选项。
- 无价值选项
- 键值对选项
注意:在本文档中,解释语法时:
- [ ] 中的任何内容都是语法/示例中的可选参数。
- 是占位符,这意味着它应该替换为实际值。
如何使用getopt?
语法:第一种形式
getopt optstring parameters
例子:
# This is correct
getopt "hv:t::" -v 123 -t123
getopt "hv:t::" -v123 -t123 # -v and 123 doesn't have whitespace
# -h takes no value.
getopt "hv:t::" -h -v123
# This is wrong. after -t can't have whitespace.
# Only optional params cannot have whitespace between key and value
getopt "hv:t::" -v 123 -t 123
# Multiple arguments that takes value.
getopt "h:v:t::g::" -h abc -v 123 -t21
# Multiple arguments without value
# All of these are correct
getopt "hvt" -htv
getopt "hvt" -h -t -v
getopt "hvt" -tv -h
这里 h,v,t 是选项,-h -v -t 是在命令行中应该如何给出选项。
- 'h' 是一个无值选项。
- 'v:' 意味着选项 -v 具有价值并且
是强制性选项。 ':' 表示有值。
- 't::' 意味着
选项 -t 具有值但是可选的。 '::' 表示可选。
在可选参数中,值不能与选项有空格分隔。因此,在“-t123”示例中,-t 是选项 123 是值。
语法:第二种形式
getopt [getopt_options] [--] optstring parameters
这里getopt之后分成五部分
- 命令本身,即 getopt
- getopt_options,它描述了如何解析参数。单破折号长选项,双破折号选项。
- --,将 getopt_options 与您要解析的选项和允许的短选项分开
- 在找到 -- 之后立即采用短选项。就像表单优先语法一样。
- 参数,这些是您传递给程序的选项。您要解析的选项并获取其上设置的实际值。
例子
getopt -l "name:,version::,verbose" -- "n:v::V" --name=Karthik -version=5.2 -verbose
语法:第三种形式
getopt [getopt_options] -o|--options optstring [getopt_options] [--] [parameters]
这里getopt之后分成五部分
- 命令本身,即 getopt
- getopt_options,它描述了如何解析参数。单破折号长选项,双破折号选项。
- 短选项,即 -o 或 --options。就像 Form first 语法,但带有选项“-o”和“--”之前(双破折号)。
- --,将 getopt_options 与您要解析的选项和允许的短选项分开
- 参数,这些是您传递给程序的选项。您要解析的选项并获取其上设置的实际值。
例子
getopt -l "name:,version::,verbose" -a -o "n:v::V" -- -name=Karthik -version=5.2 -verbose
GETOPT_OPTIONS
getopt_options 改变了命令行参数的解析方式。
以下是一些 getopt_options
选项:-l 或 --longoptions
意味着 getopt 命令应该允许多字符选项
认可。多个选项用逗号分隔。
例如,--name=Karthik 是在命令行中发送的长选项。在 getopt 中,长选项的使用类似于
getopt -l "name:,version" -- "" --name=Karthik
由于指定了 name:,该选项应该包含一个值
选项:-a 或 --alternative
意味着 getopt 命令应该允许长选项有一个破折号
'-' 而不是双破折号 '--'。
例如,您可以只使用-name=Karthik 而不是--name=Karthik
getopt -a -l "name:,version" -- "" -name=Karthik
带有代码的完整脚本示例:
#!/bin/bash
# filename: commandLine.sh
# author: @theBuzzyCoder
showHelp() {
# `cat << EOF` This means that cat should stop reading when EOF is detected
cat << EOF
Usage: ./installer -v <espo-version> [-hrV]
Install Pre-requisites for EspoCRM with docker in Development mode
-h, -help, --help Display help
-v, -espo-version, --espo-version Set and Download specific version of EspoCRM
-r, -rebuild, --rebuild Rebuild php vendor directory using composer and compiled css using grunt
-V, -verbose, --verbose Run script in verbose mode. Will print out each step of execution.
EOF
# EOF is found above and hence cat command stops reading. This is equivalent to echo but much neater when printing out.
}
export version=0
export verbose=0
export rebuilt=0
# $@ is all command line parameters passed to the script.
# -o is for short options like -v
# -l is for long options with double dash like --version
# the comma separates different long options
# -a is for long options with single dash like -version
options=$(getopt -l "help,version:,verbose,rebuild,dryrun" -o "hv:Vrd" -a -- "$@")
# set --:
# If no arguments follow this option, then the positional parameters are unset. Otherwise, the positional parameters
# are set to the arguments, even if some of them begin with a ‘-’.
eval set -- "$options"
while true
do
case $1 in
-h|--help)
showHelp
exit 0
;;
-v|--version)
shift
export version=$1
;;
-V|--verbose)
export verbose=1
set -xv # Set xtrace and verbose mode.
;;
-r|--rebuild)
export rebuild=1
;;
--)
shift
break;;
esac
shift
done
运行这个脚本文件:
# With short options grouped together and long option
# With double dash '--version'
bash commandLine.sh --version=1.0 -rV
# With short options grouped together and long option
# With single dash '-version'
bash commandLine.sh -version=1.0 -rV
# OR with short option that takes value, value separated by whitespace
# by key
bash commandLine.sh -v 1.0 -rV
# OR with short option that takes value, value without whitespace
# separation from key.
bash commandLine.sh -v1.0 -rV
# OR Separating individual short options
bash commandLine.sh -v1.0 -r -V