尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

oh-my-zsh 的 salt 插件:为 salt / salt-call / salt-cp / salt-run / salt-key 提供智能补全

oh-my-zsh 的 salt 插件:为 salt / salt-call / salt-cp / salt-run / salt-key 提供智能补全 oh-my-zsh 的 salt 插件为 salt / salt-call / salt-cp / salt-run / salt-key 提供智能补全【免费下载链接】ohmyzsh A delightful community-driven (with 2,500 contributors) framework for managing your zsh configuration. Includes 300 optional plugins (rails, git, macOS, hub, docker, homebrew, node, php, python, etc), 140 themes to spice up your morning, and an auto-update tool that makes it easy to keep up with the latest updates from the community.项目地址: https://gitcode.com/gh_mirrors/oh/ohmyzshsalt 插件是 Oh My Zsh 内置的 SaltStack 命令行补全方案。它把 SaltStack 官方仓库中的zsh_completion.zsh补全脚本以_salt文件的形式整合进 Oh My Zsh并借助 zsh 的compinit补全体系为salt、salt-call、salt-cp、salt-run、salt-key五个命令提供目标minion、执行模块、runner、密钥状态乃至输出格式的智能化补全。读完本文你将掌握如何启用该插件、理解其四类动态补全的数据来源、熟练配置补全缓存use-cache/cache-ttl并能读懂_salt补全脚本的核心实现逻辑。插件是什么一份来自 SaltStack 官方仓库的补全脚本插件的官方说明非常简洁plugins/salt/README.md 明确写道本插件是 salt 官方仓库中补全脚本pkg/zsh_completion.zsh的一份拷贝。因此插件的真正主体是 plugins/salt/_salt 这个 zsh 补全函数文件而不是通常意义上的*.plugin.zsh启动脚本。_salt文件的第一行声明了它负责补全的命令#compdef salt salt-call salt-cp salt-run salt-key#compdef是 zsh 补全系统的约定标记它告诉compinit该文件为这五个命令注册补全函数。这也是为什么该插件目录下没有salt.plugin.zsh文件——Oh My Zsh 的插件判定逻辑见下文允许插件仅由_salt形式的补全文件构成。启用插件在 .zshrc 中声明启用方式和其它插件一致在.zshrc的plugins数组中加入salt即可。plugins(git salt)默认的.zshrc模板位于 templates/zshrc.zsh-template其中第 74-78 行给出了说明与示例# Which plugins would you like to load? # Standard plugins can be found in $ZSH/plugins/ # Custom plugins may be added to $ZSH_CUSTOM/plugins/ # Example format: plugins(rails git textmate ruby lighthouse) # Add wisely, as too many plugins slow down shell startup. plugins(git)修改后重新执行source ~/.zshrc或重启终端即可生效。注意注释中的提醒插件过多会拖慢 shell 启动因为每个插件目录都会被加入补全搜索路径$fpath并参与compinit的扫描。底层机制fpath 与 compinit插件之所以能生效依赖 Oh My Zsh 启动脚本 oh-my-zsh.sh 中的两段逻辑插件目录加入$fpath第 81-98 行is_plugin()函数判定插件目录中是否存在$name.plugin.zsh或_$name文件——这正是_salt被认可为合法插件的原因随后遍历plugins数组把每个插件目录插入fpath前端is_plugin() { local base_dir$1 local name$2 builtin test -f $base_dir/plugins/$name/$name.plugin.zsh \ || builtin test -f $base_dir/plugins/$name/_$name } # ... for plugin ($plugins); do if is_plugin $ZSH_CUSTOM $plugin; then fpath($ZSH_CUSTOM/plugins/$plugin $fpath) elif is_plugin $ZSH $plugin; then fpath($ZSH/plugins/$plugin $fpath) fi done运行compinit加载补全第 132-147 行fpath组装完成之后才调用compinit它会把fpath中各目录下以_开头的补全函数包括_salt注册进补全系统并通过-d参数把补全缓存写入${ZDOTDIR:-$HOME}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}第 110 行。因此如果你手动调整了fpath却忘记重新运行compinit补全不会生效。五大命令与各自的补全行为_salt脚本末尾的_salt_comp()函数根据当前$service即被补全的命令名分发到不同的补全参数集plugins/salt/_salt 第 222-265 行命令补全内容saltminion 目标、执行模块modules、目标选择选项、通用选项、master 选项、日志选项、输出选项salt-call执行模块modules、minion 选项、通用选项、日志选项、输出选项salt-cpminion 目标、目标选择选项、通用选项、日志选项、源文件、目标文件salt-runrunner 函数、runner 选项、通用选项、日志选项salt-key密钥管理选项list/accept/reject/print/delete/finger 等并智能过滤通用选项_arguments -C中的-C表示使用子命令/多级上下文模式允许补全脚本依据命令中已出现的选项改变后续补全内容。例如salt的目标补全只有在命令中出现-E、-L、-G等目标选项时才会触发_arguments -C \ ${words[(r)$_target_opt_pat[1]]!}:minions:_minions \ :modules:_modules \ $_target_options[] \ $_common_opts[] \ $_master_options[] \ $_logging_options[] \ $_out_opts[]${words[(r)$_target_opt_pat[1]]!}的含义是若命令行中已匹配到目标选项模式则要求必须补全:minions:参数!前缀否则跳过 minion 补全。四类动态补全数据从哪里来_salt脚本最核心的价值在于它会动态查询Salt 环境而不是硬编码静态列表。它定义了三个补全函数外加一个目录定位逻辑对应四类动态数据。1. minion 补全_minions第 50-91 行通过反复调用salt-key -l type获取密钥状态为accepted已接受、unaccepted未接受、rejected已拒绝、denied已拒绝/黑名单四类 minion并存入关联数组_peonsfor type in accepted unaccepted rejected denied; do salt-key -l $type 2/dev/null | while read -r key; do [[ $key * Keys: ]] continue _peons( $key $type ) done done[[ $key * Keys: ]] continue用于跳过salt-key输出中的标题行如Accepted Keys:。补全时_minions依据命令行中的-t/-T选项过滤出对应状态的 minion若用户在命令中使用了-t all则自动展开为四种状态全部列出。针对salt与salt-cp脚本还会把上下文段名改写为minions第 55-57 行以便与下方 zstyle 缓存规则精确匹配。2. 执行模块补全_modules第 20-33 行通过salt-call --local --log-level error --out txt sys.list_functions查询本机可用的执行函数再经字符串处理后作为补全候选_funcs( ${${(Q)${${(s. .)$(_call_program salt-call-cmd salt-call --local --log-level error --out txt sys.list_functions)}%%[],]##}#\[}:#local:} )该命令在--local模式下运行因此无需连接 master即可工作。--log-level error用于抑制日志输出--out txt保证输出为纯文本、便于解析。3. runner 补全_runners第 35-48 行与模块补全对称通过salt-call --local --log-level error --out txt sys.list_runner_functions查询 runner 函数列表用于salt-run命令的补全。4. salt 安装目录定位第 267-277 行脚本通过 Python 导入salt模块并打印其__file__来定位 Salt 的安装目录从而为--returnreturner、--outoutputter等选项提供基于目录的补全salt_dir${$(python2 -c import sys; del sys.path[0]; import salt; print(salt.__file__);)%__init__*}%__init__*负责把路径中的__init__.py后缀裁掉。随后该目录被用于_path_files -W $salt_dir/returners -g [^_]*.py(\:r)之类的文件补全。需要提醒的是脚本内写死的是python2在已移除 Python 2 的现代系统上该步骤会失败此时 returner/outputter 的目录补全可能退化为不可用——这是沿用官方上游脚本带来的已知限制。缓存机制避免每次按 Tab 都查询 Salt动态查询虽然准确但salt-key、salt-call都是有开销的子进程调用。为此_salt脚本深度集成了 zsh 的补全缓存体系这也是脚本头部注释第 1-15 行重点说明的内容。启用缓存use-cache在.zshrc中设置 zstyle 即可开启三类数据的缓存# 全部缓存 zstyle :completion:*:salt(|-cp|-call|-run|-key):* use-cache true # 按需选择性缓存/关闭 zstyle :completion::complete:salt-key:set-option-a-1: use-cache false zstyle :completion::complete:salt(|-cp|-call):minions: use-cache true zstyle :completion::complete:salt(|-call):modules: use-cache true zstyle :completion::complete:salt(|-cp|-call|-run|-key):salt_dir: use-cache true第一行通配*一次性开启全部缓存后续行用于更精细的控制。注意salt(|-cp|-call|-run|-key)这种写法是 zsh 的扩展通配符语法它同时匹配salt、salt-cp、salt-call、salt-run、salt-key五种上下文。缓存过期策略cache-ttl缓存校验时长由cache-ttl控制接受数字 单位两个参数单位支持seconds、days、hours、weeks、months# 四天后使 minion 缓存失效 zstyle :completion::complete:salt(|-cp|-call):minions: cache-ttl 4 days对应的解析逻辑位于_salt_caching_policy()函数第 93-112 行它读取cache-ttl的值将单位映射为 zsh 文件修改时间运算符s/d/w/h/M默认单位为天、默认时长为 1然后与缓存文件的mtime进行比较_salt_caching_policy() { local oldp ttl d t zstyle -a :completion:$curcontext: cache-ttl ttl if (( $#ttl 2 )); then [[ $ttl[1] - ]] integer t$ttl[1] case $ttl[2] in seconds#)ds;; months#) dM;; weeks#) dw;; hours#) dh;; *) dd;; esac fi oldp( $1(Nm${d:-d}${t:-1}) ) (( $#oldp )) }$1(Nm...)是 zsh 的 glob 限定符m表示按修改时间筛选t表示t 时间之前修改——因此当缓存文件在 ttl 之前被修改即过期时$#oldp为 0函数返回失败触发缓存重建。缓存策略的自动装载_modules、_runners、_minions以及 salt_dir 定位逻辑中都包含同一段守卫代码if ! zstyle -m :completion:$curcontext: cache-policy *; then zstyle :completion:$curcontext: cache-policy _salt_caching_policy fi其作用是如果用户没有显式自定义cache-policy就自动把_salt_caching_policy设为该上下文的默认缓存策略。用户在.zshrc中自行设置cache-policy可以完全覆盖此默认行为。选项补全五组参数全面覆盖_salt脚本将五个命令的选项组织成多个数组其中_target_options、_common_opts、_master_options、_minion_options、_runner_options、_key_options、_logging_options、_out_opts在脚本第 114-220 行集中定义。这些定义同时携带帮助文本按 Tab 时可直接看到选项含义。目标选择选项_target_options第 120-130 行这是 Salt 最富特色的部分——八种目标选择方式全部支持补全选项短选项说明--pcre-E使用 PCRE 正则表达式匹配目标--list-L使用逗号或空格分隔的服务器列表--grain-G按 grain 值匹配目标--grain-pcre-按 grain 值支持正则匹配--nodegroup-N使用预定义的 nodegroup 匹配--range-R使用 range 表达式匹配--compound-C组合多种目标匹配方式--pillar-I按 pillar 值匹配目标--ipcidr-S按子网CIDR或 IPv4 地址匹配脚本第 115-118 行的_target_opt_pat定义了互斥模式-E/-L/-G/-N/-R/-C/-I/-S之间互相排斥-前缀表示互斥一旦命令行中出现其中一个补全系统会自动隐藏其余目标选项避免写出自相矛盾的目标命令。通用选项_common_opts第 132-138 行所有命令共享--version、--versions-report、-h/--help、-c/--config-dir默认/etc/salt/补全为目录、-t/--timeout默认 5 秒。master 专属选项_master_options第 140-153 行用于salt命令-s/--static等所有 minion 返回后统一输出、--async异步执行不等待回复、--state-output输出级别 full/terse/mixed/changes、--subset随机子集执行、-v/--verbose、--hide-timeout、-b/--batch批处理模式支持数字或百分比、-a/--auth外部认证 eauth、-T/--make-token、--returnreturner按$salt_dir/returners目录补全、-d/--doc模块文档、--args-separator。minion 专属选项_minion_options第 155-168 行用于salt-call-g/--grains输出 grains 信息、-m/--module-dirs附加模块目录、--master、--local无 master 本地运行、--file-root、--pillar-root、--retcode-passthrough、--id、--skip-grains、--refresh-grains-cache。salt-key 密钥选项_key_options第 175-206 行密钥管理操作全覆盖且-l/--list的候选值带有说明文本{-l,--list}[list public keys]:key type:(( preaccepted\:unaccepted/unsigned keys unaccepted\:unaccepted/unsigned keys un\:unaccepted/unsigned keys accepted\:accepted/signed keys acc\:accepted/signed keys rejected\:rejected keys rej\:rejected keys den\:denied keys denied\:denied keys all ))密钥参数-a/--accept、-r/--reject、-p/--print、-d/--delete、-f/--finger均复用_minions补全并按状态过滤例如--accept只补全unaccepted附带-T rejected以支持--include-all场景。此外还包括-A/--accept-all、-P/--print-all、-D/--delete-all、-F/--finger-all、-q/--quiet、-y/--yes、-u/--user、--rotate-aes-key布尔值 true/false 补全、密钥生成相关--gen-keys、--gen-keys-dir、--keysize、--gen-signature、--priv、--pub、--signature-path、--auto-create以及--include-all。有意思的细节脚本会检查命令行中是否出现--include-all(( words[(I)--include-all] ))第 81 行只有出现时才把-T选项纳入考虑否则忽略之。日志与输出选项_logging_options、_out_opts第 208-220 行日志级别候选值完整all garbage trace debug info warning error critical quiet日志文件默认路径/var/log/salt/master。输出选项包括--out/--outputoutputter 按$salt_dir/output目录补全、--out-indent、--out-file、--no-color/--no-colour、--force-color/--force-colour。salt-key在组装补全参数时还做了一次剔除第 261-262 行由于-l已被密钥列表占用它从通用选项中剔除-t --timeout从日志选项中剔除-l --log-level避免选项短名冲突。实战建议与注意事项启用缓存建议在.zshrc中开启use-cache并按需设置cache-ttl例如 minion 列表 1 小时、模块列表 1 天否则每次补全都要 fork 出salt-key/salt-call子进程在 minion 数量较大或 master 连接缓慢时会有明显延迟。minion 补全依赖本机密钥_minions通过本机salt-key查询密钥状态因此仅在能够连接 master 且本机安装了 salt-key 的环境下才有完整效果_modules与_runners走--local模式脱离 master 也能工作。Python 版本注意salt_dir定位使用python2在纯 Python 3 环境下该步骤会失败相关 returner/outputter 目录补全不可用这是上游补全脚本沿袭的历史实现使用时可留意。修改.zshrc后重新加载新增插件后需source ~/.zshrc重新触发 oh-my-zsh.sh 中的compinit若补全未生效可检查~/.zcompdump-*是否已包含_salt相关内容可用compinit -C或删除 zcompdump 后重启 shell 强制重建。整体而言salt 插件的价值在于把查询 Salt 环境和zsh 补全无缝衔接minion、模块、runner 三类数据全部实时取自真实环境选项定义完整覆盖 master、minion、key 管理三大命令面配合 zstyle 缓存体系兼顾了准确性与响应速度。其全部实现均集中在 plugins/salt/_salt 单个文件中适合作为学习 zsh 动态补全_arguments -C、zstyle缓存、glob 限定符的优质范例。【免费下载链接】ohmyzsh A delightful community-driven (with 2,500 contributors) framework for managing your zsh configuration. Includes 300 optional plugins (rails, git, macOS, hub, docker, homebrew, node, php, python, etc), 140 themes to spice up your morning, and an auto-update tool that makes it easy to keep up with the latest updates from the community.项目地址: https://gitcode.com/gh_mirrors/oh/ohmyzsh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表