首页 > 解决方案 > 如何在 zsh 中创建可以接受乱序参数的脚本?

问题描述

所以我在 zsh 中编写了一个可以接受多个参数的小脚本。但是,用户碰巧无序地传递参数。例如,这将是对脚本的有效调用:

./logproc.sh --include /var/log --exclude-file-ext gz,bz --show-only

现在,我可以使用位置参数(如 $1、$2 等)先期待--include,然后--exclude-file-ext依此类推。但是用户是这样调用脚本的:

./logproc.sh --show-only --exclude-file-ext gz,bz --include /var/log

或者

./logproc.sh --exclude-file-ext gz,bz --show-only --include /var/log

随着时间的推移,添加更多功能的需求正在增加,并且确定哪些参数被传递给脚本的排列和组合将会爆炸。

zsh 中是否有内置工具或命令(可以在脚本中调用的外部工具)可用于找出发送到脚本的参数?

PS:我正在寻找 ZSH 特定的解决方案。

标签: functionshellscriptingzsh

解决方案


传统上,shell 内置命令getopts用于处理脚本参数。从您的示例看来,您似乎需要支持长选项(这是短选项:-s这是长选项--long),但是大多数 shell,包括 zsh,在其 getopts 的实现中不支持长选项。如果绝对有必要使用 POSIX 兼容工具,那么已经存在各种实现,例如getopts_long

大多数时候,另一个工具是可用的——GNU getopt。这个支持这两个选项,默认情况下在大多数 Linux 发行版上都可用。您可以在手册页getopt(3)中找到详尽的示例和描述。

zsh 变体 -zparseopts

zsh 有另一个选项叫做zparseopts. 您可以在zshmodules(1)的文档中找到描述和更多示例。最后,这是您案例的代码片段:

#!/bin/zsh

zparseopts -E -D -- \
           -include:=o_include \
           -exclude-file-ext:=o_exclude \
           -show-only=o_show

echo "include: ${o_include[2]}"
echo "exclude: ${o_exclude[2]}"
echo "show? ${o_show}"

推荐阅读