Linux Shell 脚本处理命令行参数核心是位置参数($1、$2 等)和 getopts 解析短选项;需用 ”$1″ 防空值报错、"$@" 保分词,getopts 支持 -a -b -c arg 格式,长选项可用 set 预处理转换,最后须校验参数有效性并设默认值。

Linux Shell 脚本里处理命令行参数,核心就两件事:用好位置参数($1、$2……)读取简单输入,再用 getopts 规范解析带选项的参数(比如 -f file.txt -v --help)。不依赖外部 工具,纯 Bash 内置功能就能搞定大多数场景。
位置参数:最基础也最容易出错的入口
脚本运行时,空格分隔的每个词自动成为位置参数:$0 是脚本名,$1 是第一个参数,$2 是第二个……$# 告诉你一共几个参数,$@ 和 $* 则代表全部参数(区别 在于引号包裹行为,日常推荐用 "$@" 保留原始分词)。
常见误区是直接写 if [$1 = "start"] —— 如果没传参数,$1 展开为空,变成 if [= "start"],语法报错。安全写法是加引号:
if ["$1" = "start"]; then ……- 检查参数个数:
if [$# -lt 1]; then echo "Usage: $0 <command>"; exit 1; fi</command> - 批量处理所有参数:
for arg in "$@"; do echo "Got: $arg"; done
getopts:解析短选项的标准方式
getopts 是 Bash 内置命令,专为解析形如 -a -b value -c 或 -abv filename 的传统 Unix 风格选项设计。它不支持长选项(--help),但足够轻量可靠。
基本结构是 while getopts "ab:c" opt; do …… done,其中字符串 "ab:c" 定义合法选项:a 和 b 是开关型选项,c 后跟冒号表示它需要参数(如 -c file.txt)。
- 每次循环,
opt变量存当前解析到的选项字母(如a、b) - 需要参数的选项,其值自动存入
OPTARG - 遇到非法选项,
opt被设为?,可借此报错退出 - 解析结束后,
$OPTIND指向第一个非选项参数的位置(可用于获取剩余位置参数)
示例片段:
while getopts "vhd:f:" opt; do case $opt in v) verbose=1 ;; h) echo "Usage: $0 [-v] [-h] [-d dir] [-f file]"; exit 0 ;; d) target_dir="$OPTARG" ;; f) input_file="$OPTARG" ;; :) echo "Option -$OPTARG requires an argument."; exit 1 ;; ?) echo "Unknown option: -$OPTARG"; exit 1 ;; esac done shift $((OPTIND-1)) # 跳过已处理的选项,$@ 现在只含剩余参数 if [$# -gt 0]; then echo "Non-option args: $@" fi
长选项怎么办?简单补丁就够了
getopts 不原生支持 --help 这类长选项,但不需要上 getopt(注意末尾多一个 t)这种复杂工具。常见做法是预处理:在进入 getopts 前,把长选项转成等价短选项。
if [["$1" == "--help"]]; then set -- "-h"; fiif [["$1" == "--verbose"]]; then set -- "-v" "$@"; fi- 更通用的转换可用 case + shift 实现,例如匹配
--dir=xxx并转为-d xxx
这样既保持 getopts 的简洁性,又兼顾了用户习惯。
别忘了参数校验和默认值
解析只是第一步。真实脚本中,必须验证关键参数是否合理:
- 文件路径是否存在:
[-f "$input_file"] || {echo "Error: $input_file not found"; exit 1;} - 目录是否有写权限:
[-w "$target_dir"] || {echo "No write access to $target_dir"; exit 1;} - 给变量设默认值:
verbose=${verbose:-0},或更安全地verbose=${verbose:-""}再判断 - 避免覆盖重要 环境变量,必要时用
local声明函数内变量
参数处理不是终点,而是后续逻辑可靠的起点。






























