Shell 脚本参数解析
Posted
技术标签:
【中文标题】Shell 脚本参数解析【英文标题】:Shell script argument parsing 【发布时间】:2011-02-08 05:16:54 【问题描述】:关于这类事情有很多问题,但假设我们的目标是安装了 getopt 和 getopts 的通用 Linux 系统(我们也不会使用,但它们似乎很受欢迎)
如何解析长参数(--example | --example simple-option)和短参数(-e | -esimple-example | -e simple-example)
【问题讨论】:
【参考方案1】:您想将getopt
与多头和空头选项一起使用。工作代码示例:
# Parse arguments
TEMP=$(getopt -n $PROGRAM_NAME -o p:P:cCkhnvVS \
--long domain-password:,pop3-password:\
,create,cron,kill,help,no-sync-passwords,version,verbose,skip-pop3 \
-- "$@")
# Die if they fat finger arguments, this program will be run as root
[ $? = 0 ] || die "Error parsing arguments. Try $PROGRAM_NAME --help"
eval set -- "$TEMP"
while true; do
case $1 in
-c|--create)
MODE="CREATE"; shift; continue
;;
-C|--cron)
MODE="CRON"; shift; continue
;;
-k|--kill)
MODE="KILL"; shift; continue
;;
-h|--help)
usage
exit 0
;;
-n|--no-sync-passwords)
SYNC_VHOST=0; shift; continue
;;
-p|--domain-password)
DOMAIN_PASS="$2"; shift; shift; continue
;;
-P|--pop3-password)
POP3_PASS="$2"; shift; shift; continue
;;
-v|--version)
printf "%s, version %s\n" "$PROGRAM_NAME" "$PROGRAM_VERSION"
exit 0
;;
-v|--verbose)
VERBOSE=1; shift; continue
;;
-S|--skip-pop3)
SKIP_POP=1; shift; continue
;;
--)
# no more arguments to parse
break
;;
*)
printf "Unknown option %s\n" "$1"
exit 1
;;
esac
done
注意,die
是之前定义的函数(未显示)。
-n
选项告诉 getopt 将错误报告为我的程序名称,而不是 getopt
。 -o
定义了一个短选项列表(:
在选项之后表示需要的参数),--long
指定长选项列表(对应于短选项)。
剩下的只是一个简单的开关,适当地调用shift
来推进参数指针。请注意,拨打shift; shift;
只是一个顽固的习惯。在当前的现代世界中,shift 2
可能就足够了。
现代的 getopt 在较新的平台上非常一致,但是您可能会在较旧的(大约 Redhat 9 之前的)系统上遇到一些可移植性问题。有关向后兼容性的信息,请参阅man getopt
。但是,您不太可能会遇到对它的需求。
最后,解析完options后,可以再次调用:
eval set -- "$@"
这会将参数指针移动到 getopt 完成解析选项后留在命令行上的任何其他内容。然后你可以shift
继续阅读它们。例如,如果一个命令看起来像这样:
./foo --option bar file1.txt file2.txt file3.txt
完成后,别忘了创建一个方便的-h / --help
选项来打印您的新奇选项。 :) 如果您使该输出 help2man 友好,那么您就有一个即时手册页可以与您的新工具一起使用。
编辑
在大多数发行版中,您可以在 /usr/share/doc/util-linux/examples
中找到更多示例 getopt
代码,默认情况下应该已安装。
【讨论】:
我确实意识到我在这里没有理智地检查设置模式的多个命令。在这种情况下,最后一个选项优先是可以接受的,并且粘贴只是为了提供有关使用getopt
的一种方式的信息。
我已经多次被提及使用getopt()
。叫我笨蛋,但我就是不明白它是如何工作的。由于我的脚本需要一个等效的 Windows,我 used this。在我看来,这是一种更清洁且不那么神奇的方法。我可以在 linux 上做类似的事情吗?
@Christian 你可以用 BASH 做类似的事情,%1
变成 $1
(如果 $1
需要一个参数,则分别是 $2
)。事实上,很多人就是这样做的,通过shift
不断循环参数并通过开关运行当前参数。 getopt
只是处理所有这些魔法,并为您提供强制参数检查,很多人都喜欢这种便利。
谢谢蒂姆。我明白为什么getop
更好,我只是无法在不到 10 分钟的时间内弄清楚它是如何工作的,与简单的 1:1 翻译相比,这对我的任务来说太多了。另外,让两个脚本都遵循相同的代码模式可以更容易维护。无论如何,感谢您对此的洞察力。以上是关于Shell 脚本参数解析的主要内容,如果未能解决你的问题,请参考以下文章