shell脚本通过位置参数($1、$2…)、特殊变量($#、$@、$\*、$0)获取命令行参数;$@推荐用于安全遍历,需加双引号;getopts支持短选项解析,getopt支持长选项,二者适用场景不同。

Shell脚本中获取命令行参数,主要靠位置参数($1、$2…)和特殊变量(如$#、$@、$*、$0),配合getopts或while getopts可支持带选项的灵活传参。
基础位置参数:按顺序取值
执行 ./script.sh a b c 时:
-
$0是脚本名(如./script.sh) -
$1是第一个参数a,$2是b,$3是c -
$#返回参数个数(这里是3) -
$@展开为"a" "b" "c"(各参数独立字符串,推荐用于遍历) -
$*展开为"a b c"(单个字符串,中间空格分隔)
安全遍历所有参数:用 for arg in "$@"
避免含空格或特殊字符的参数被错误分割,必须加双引号:
for arg in "$@"; do echo "参数:$arg" done
不带引号的 for arg in $@ 会导致 "file name.txt" 被拆成两个词。
解析带选项的参数:用 getopts
支持短选项(如 -f file -v),自动处理选项和参数绑定:
while getopts "f:v" opt; do
case $opt in
f) file="$OPTARG" ;; # -f 后必须跟值
v) verbose=1 ;; # -v 是开关型选项
\?) echo "未知选项:-$OPTARG" >&2; exit 1 ;;
esac
done
说明:
-
getopts "f:v"中,f:表示-f必须带参数,v表示-v是无参开关 -
$OPTARG存储-f后面的值(如-f /tmp/log→$OPTARG = "/tmp/log") - 解析完后,剩余非选项参数从
$((OPTIND))开始,可用shift $((OPTIND-1))跳过已处理部分
进阶:支持长选项(--help、--output=xxx)
原生 getopts 不支持长选项,可用 getopt(注意是外部命令,不是内置 getopts):
args=$(getopt -o hf:v --long help,file:,verbose -n "$0" -- "$@") eval set -- "$args" <p>while true; do case "$1" in -h|--help) echo "用法:$0 [-h] [-f FILE] [-v]"; exit 0 ;; -f|--file) file="$2"; shift 2 ;; -v|--verbose) verbose=1; shift ;; --) shift; break ;; *) echo "错误参数"; exit 1 ;; esac done</p>
注意:getopt 输出需用 eval set -- 重置位置参数,才能继续用 $1、$2 取值。
不复杂但容易忽略细节,关键是引号保护、选项冒号规则、以及区分 getopts(内置,简单)和 getopt(外部,支持长选项)的适用场景。











