推荐使用getopts处理短选项(如-f、-v)、getopt支持长选项(如--file),或手动解析;需引用变量、设默认值、校验参数并避免覆盖内置变量。

在 Linux 脚本中处理带标志(flag)的命名命令行参数,推荐使用 getopts(适用于简单短选项)或 getopt(支持长选项和复杂解析)。下面分场景说明实用方法。
用 getopts 处理短选项(如 -f, -v, -h)
getopts 是 Bash 内置命令,轻量、可靠,适合脚本内部解析形如 ./script.sh -f file.txt -v 的参数。
- 语法格式:
while getopts "f:vh" opt; do ... done,其中f:表示-f必须带参数,v和h是无参开关 -
$OPTARG自动保存-f后面的值(如file.txt) -
$OPTIND记录下一个待处理参数位置,可用于跳过已解析部分
示例:
#!/bin/bash
while getopts "f:vh" opt; do
case $opt in
f) filename="$OPTARG" ;;
v) verbose=1 ;;
h) echo "Usage: $0 -f <file> [-v] [-h]"; exit 0 ;;
*) echo "Unknown option: -$OPTARG" >&2; exit 1 ;;
esac
done
echo "File: ${filename:-not set}, Verbose: ${verbose:-0}"
</file>
用 getopt(增强版)支持长选项(如 --file, --verbose)
系统自带的 getopt(注意不是 getopts)可解析长选项和混排参数,需配合 eval 或数组重设 $@。推荐使用其增强模式(getopt -o ... -l ... -- "$@")。
-
-o f:vh定义短选项规则(同 getopts) -
-l file:,verbose,help定义长选项,冒号表示该长选项需参数 -
-- "$@"明确分隔选项与非选项参数(防文件名含短横线出错)
示例片段:
#!/bin/bash
args=$(getopt -o f:vh -l "file:,verbose,help" -- "$@")
eval set -- "$args"
while true; do
case "$1" in
-f|--file) filename="$2"; shift 2 ;;
-v|--verbose) verbose=1; shift ;;
-h|--help) echo "Help shown"; exit 0 ;;
--) shift; break ;;
*) echo "Internal error"; exit 1 ;;
esac
done
echo "File: ${filename:-none}, Verbose: $verbose"
手动解析(适合极简或兼容性要求高场景)
若无法依赖 getopt(如最小化容器环境),可用 while + case 手动遍历 $@:
- 用
shift逐个消费参数 - 区分
-f file和-f=file等写法时需额外判断(如[[ $1 == -f=* ]]) - 注意空格和引号:用户输入
./s.sh -f "my file.txt"中"my file.txt"会被自动合并为一个参数
小技巧:先用 set -- $(getopt ...) 预处理,再手动解析,兼顾健壮性和控制力。
关键提醒
无论用哪种方式,都应:
- 始终引用变量:
"$filename"防路径含空格或特殊字符 - 设置默认值:
filename=${filename:-/dev/stdin} - 校验必需参数是否存在,缺失时给出清晰提示并退出
- 避免覆盖内置变量(如别用
opt作其他用途,getopts会改写它)
不复杂但容易忽略。











