如何在 zsh 中创建可以接受无序参数的脚本?

Vai*_*hal 8 shell scripting zsh function

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

./logproc.sh --include /var/log --exclude-file-ext gz,bz --show-only
Run Code Online (Sandbox Code Playgroud)

现在,我可以使用 $1、$2 等位置参数来期望--include首先、然后--exclude-file-ext等等。但用户是这样调用脚本的:

./logproc.sh --show-only --exclude-file-ext gz,bz --include /var/log
Run Code Online (Sandbox Code Playgroud)

或者

./logproc.sh --exclude-file-ext gz,bz --show-only --include /var/log
Run Code Online (Sandbox Code Playgroud)

随着时间的推移,添加更多功能的需求不断增加,并且确定传递给脚本的参数的排列和组合将会呈爆炸式增长。

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

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

小智 19

传统上,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}"
Run Code Online (Sandbox Code Playgroud)