devops-exercises 的 Bash 参数数量检查实战:用 case 语句编写健壮的 CLI 参数校验脚本
文档教程DevOps运维【免费下载链接】devops-exercisesLinux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions项目地址https://gitcode.com/GitHub_Trending/de/devops-exercises点击查看免费下载导读本指南围绕 devops-exercises 仓库中 Number of Arguments 练习展开该练习是仓库 Shell 脚本训练体系中「Case Statementcase 分支语句」主题下的基础实操题。通过本指南你将掌握 Bash 位置参数$#、$1的读取方式、case语句对参数数量的多分支判断以及函数封装配合set -eu编写可退出码反馈的 CLI 脚本的完整思路并能在终端中直接运行、验证结果。一、练习目标一份可运行的 CLI 参数校验需求原练习文件 topics/shell/num_of_args.md 给出了三条明确的行为目标本质上是在定义一个参数数量感知的命令行小程序场景应输出内容恰好传入 1 个参数Got it: argument value回显该参数未传入任何参数Usage: ./program name argument提示用法传入多于 1 个参数hey hey...too many!拒绝过量的输入该练习在 topics/shell/README.md 的练习索引表中被标记为Basic基础难度与Argument Check、Sum等题目同属一个渐进式训练序列——前面已经用 hello_world.md 覆盖变量、用 argument_check.md 覆盖条件判断本练习则聚焦于依据参数个数做多路分支属于参数校验的经典入门场景。二、官方解决方案case 语句的完整实现仓库在 topics/shell/solutions/num_of_args.md 给出了官方参考实现全文如下#!/usr/bin/env bash set -eu main() { case $# in 0) printf %s Usage: ./program name argument; return 1 ;; 1) printf %s Got it: $1; return 0 ;; *) return 1 ;; esac } main $这段脚本虽短却包含了几个值得拆解的关键设计1. Shebang 与解释器选择#!/usr/bin/env bash通过env在PATH中查找bash比硬编码#!/bin/bash更便携。仓库 topics/shell/README.md 的自测题也解释了 Shebang 的含义/bin/bashBourne-again shell是 Linux 默认登录 shell 中最常用的解释器功能丰富、语法完善因此大量脚本以其为解释器。2.set -eu脚本健壮性的两道保险-e一旦脚本中某条命令返回非零退出码脚本立即退出避免错误发生后继续往下执行的隐患仓库 README 自测题明确提到Bash 默认会在命令失败后继续运行后续命令而set -e可改变这一行为-u引用未定义变量时直接报错退出防止拼写错误或遗漏赋值导致静默使用空值。set -eu在该仓库中被视为脚本标配CI 脚本 scripts/run_ci.sh 用的是更严格的set -euo pipefail额外增加-o pipefail使管道中任一环节失败都触发退出统计脚本 scripts/count_questions.sh 同样以set -eu开头。可以看到这正是仓库贯穿始终的 Bash 最佳实践。3.main函数封装将逻辑放入main()函数、末尾以main $统一调用是仓库 Shell 练习的一贯风格。这种做法的好处在于所有变量局部化在函数作用域内避免污染全局命名空间函数天然支持return退出码便于将脚本行为组织为成功返回 0、失败返回 1的语义同一套路也出现在 Sum 练习的官方解答 中function sum { echo $(( $1 $2 )) }说明函数 参数传递是该仓库推荐的脚本组织方式。4.case $#按参数个数分流$#是 Bash 内置位置参数之一表示当前脚本或函数收到的参数总数。case $# in就是对参数个数做模式匹配这正是本练习的题眼。各分支含义0)无参数时打印用法提示并return 1非零退出码表示调用方式错误1)恰好一个参数时打印Got it: $1并return 0成功*)兜底分支匹配任意其他情况即 2 个及以上参数官方解答在此仅return 1。5. 需要指出的一个细节差异细心对照会发现原练习目标要求多于一个参数时打印hey hey...too many!而仓库给出的官方解答在*)分支只return 1、并未打印该消息。因此若想 100% 复现练习目标可以在*)分支补上输出。这也是本指南下文将提供完整合规版本的原因——理解目标也要理解仓库参考实现的取舍。三、Bash case 语句语法、模式与执行流case是 Bash 内置的多分支条件结构语法如下case 表达式 in 模式1) 命令序列 ;; 模式2) 命令序列 ;; *) 兜底命令序列 ;; esac要点说明每个分支以)结尾命令序列以;;结束;;可继续尝试后续分支但本练习用不到模式支持通配符与|多模式如a|A)同时匹配小写与大写*)匹配任意值作为兜底与if/then/elif相比case在读代码时模式一览无余特别适合对同一个变量做多路取值判断——本例的被判断变量正是$#三个分支精确覆盖 0、1、其余三种情况无需繁琐的数值比较写法。如果想用if实现等价逻辑可写成if [ $# -eq 0 ]; then printf %s\n Usage: ./program name argument exit 1 elif [ $# -eq 1 ]; then printf %s\n Got it: $1 exit 0 else printf %s\n hey hey...too many! exit 1 fi两种写法功能等价但case版本结构更紧凑、模式扩展更自然这也是仓库练习将本题归类为 Case Statement 主题的原因。四、位置参数全景$#、$1、$、$* 与 $0要真正理解本题需要掌握 Bash 位置参数家族。仓库 topics/shell/README.md 的自测题区恰好覆盖了这些概念变量含义本题中的角色$0脚本自身名称用法提示中的program name可用它动态替换$1…$9第 1 至第 9 个位置参数$1是被回显的第一个参数${10}…第 10 个及以后的参数需花括号超长参数列表时使用$#位置参数的总个数本题的分支判断依据$全部参数组成的数组main $原样透传所有参数$*全部参数拼成的单个字符串与$的区别见下仓库自测题特别强调了两点$是所有参数的数组$*是所有参数的单个字符串——当参数中含空格时$能保持每个参数独立推荐用法$*则会合并成一个字符串可能改变语义echo $1即可打印第一个参数见 README 自测题 How to print the first argument passed to a script?。补充一点在用法提示中./program name直接硬编码了脚本名实操中更稳妥的做法是用$0动态获取例如printf %s\n Usage: $0 argument这样即使脚本被重命名或通过绝对路径调用提示依然准确。五、完整合规增强版逐条满足全部练习目标结合官方解答的结构、原练习的三条目标以及上文提到的$0动态脚本名这里给出一个逐行注释、可直接复制运行的完整版本#!/usr/bin/env bash set -eu main() { case $# in # 目标 2无参数时打印用法提示并以退出码 1 表示用法错误 0) printf %s\n Usage: $0 argument return 1 ;; # 目标 1恰好一个参数时回显该参数退出码 0 表示成功 1) printf %s\n Got it: $1 return 0 ;; # 目标 3多于一个参数时打印提示并以非零退出码拒绝 *) printf %s\n hey hey...too many! return 1 ;; esac } # 透传全部位置参数main 内部的 $#、$1 即来自脚本调用处 main $运行与验证将脚本保存为num_of_args.sh后在终端中执行chmod x num_of_args.sh # 授予执行权限若直接以 bash num_of_args.sh 运行可省略 ./num_of_args.sh hello # 期望输出: Got it: hello 退出码 0 ./num_of_args.sh # 期望输出: Usage: ./num_of_args.sh argument退出码 1 ./num_of_args.sh a b # 期望输出: hey hey...too many!退出码 1 ./num_of_args.sh a b c d # 同样落入 *) 分支输出 hey hey...too many!每条命令执行后可通过echo $?查看上一条命令的退出码验证与设计一致。由于设置了set -u若在调用处误传了未定义变量脚本会立即报错退出这正是set -eu为参数校验脚本提供的额外防线。六、从练习到实战参数校验的进阶组合单个练习只是起点将本题与仓库中相邻练习组合即可拼出更完整的 CLI 健壮性方案1. 结合正则校验参数内容。Sum 练习的官方解答 展示了如何在数量校验之后继续做内容校验re^[0-9]$ if ! [[ $1 ~ $re $2 ~ $re ]]; then echo Oh no...I need two numbers exit 2 fi模式^[0-9]$匹配纯数字串[[ ... ~ ... ]]是支持正则的测试语法exit 2用非 0、非 1 的退出码表达输入不合法。可见先case $#校验数量再~正则校验内容是仓库练习所体现的分层校验范式。2. 结合条件判断的简洁写法。Argument Check 练习的解答 展示了[[ ... ]] echo ... || echo ...的三元式写法适合单条件快速判断而参数数量这种多路场景case明显更合适——两种手法互为补充。3. 结合脚本级 CI 校验。仓库用 scripts/run_ci.sh 对所有 Markdown 练习文档做语法 lint并规定set -euo pipefail、flake8 等规范在为实战编写参数校验脚本时同样建议以set -euo pipefail起步把数量校验与内容校验分层实现并让每个错误路径都返回明确且可区分的退出码。七、小结通过 devops-exercises 仓库的 Number of Arguments 练习我们完整走通了需求目标 → case 多分支 → 位置参数 → 函数封装 → 退出码设计 → 运行验证的 CLI 参数校验全流程。核心收获可归纳为三点用$#case做参数数量分流是 Bash 中最直观、可扩展的多路校验写法set -eu实战中升级为set -euo pipefail与main $函数封装是仓库贯穿始终的脚本健壮性标配数量校验与内容校验分层case $#之后接~正则是通向生产级 CLI 脚本的进阶路径。你可以随时回到仓库继续练习同主题下的其他题目Argument Check、Sum、Print Arguments或在 topics/shell/README.md 的自测题区验证自己对$、$*、$#等概念的掌握程度。赞分享文档教程DevOps运维【免费下载链接】devops-exercisesLinux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions项目地址https://gitcode.com/GitHub_Trending/de/devops-exercises点击查看免费下载相关推荐Bash 目录比较实战用 diff -r 与参数校验编写可复用的目录差异检查脚本Bash 目录比较实战用 diff r 与参数校验编写可复用的目录差异检查脚本 本篇指南以 devops exercises 仓库的 Shell 练习「Dir文档教程DevOps运维Aspire ATS 第三方集成属性指南无需引用 Aspire.Hosting 也能让集成被 Aspire 类型系统识别Aspire ATS 第三方集成属性指南无需引用 Aspire.Hosting 也能让集成被 Aspire 类型系统识别 Aspire Type System文档教程DevOps运维MaterialDialog-Android对话框状态监听OnShow、OnCancel与OnDismiss使用指南MaterialDialog Android对话框状态监听OnShow、OnCancel与OnDismiss使用指南 MaterialDialog Andro上一篇DeepSeek Harness TUI 助手消息时序改进标签置顶、计时置底的渲染决策解析下一篇混合精度训练可视化TensorBoard监控Apex动态全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →