【Linux知识】Shell 脚本参数详解:从基础到高级应用

Shell 脚本参数详解:从基础到高级应用

Shell 脚本参数详解:从基础到高级应用

Shell 脚本通过参数接收用户输入,实现动态行为。以下是各类参数的详细说明、使用场景及示例:

一、基础位置参数

脚本执行时传入的参数按顺序分配:

bash 复制代码
./script.sh arg1 arg2 arg3
符号 含义 示例 说明
$0 脚本自身名称 echo $0./script.sh 包含路径(可用 basename $0 提取纯文件名)
$1 第一个参数 echo $1arg1 若参数含空格需用引号包裹:"./script.sh 'hello world'"
$2 第二个参数 echo $2arg2
$n 第 n 个参数 $3arg3 超过 9 时需用花括号:${10}
$# 参数总数 echo $#3 常用于循环控制
$* 所有参数(单字符串) echo $*arg1 arg2 arg3 IFS 分隔(默认空格)
$@ 所有参数(独立字符串) for i in "$@"; do ... 推荐使用,保留参数边界(即使含空格)

📌 关键区别

bash 复制代码
args=("a b" c)  # 两个参数:第一个是"a b",第二个是"c"
for x in "$*"; do echo "[$x]"; done  # 输出:[a b c](合并为单字符串)
for x in "$@"; do echo "[$x]"; done  # 输出:[a b] 和 [c](独立字符串)
二、特殊状态参数
符号 含义 示例场景
$? 上一条命令的退出状态码 `grep "text" file
$$ 当前脚本的进程 ID (PID) echo "PID: $$"PID: 12345(用于日志/锁文件)
$! 最后一个后台进程的 PID sleep 100 & echo "Background PID: $!"Background PID: 12346
$_ 上一条命令的最后一个参数 ls /tmp; cd $_ → 进入 /tmp 目录
$- 当前 Shell 的选项标志 echo $-hB(显示 set 启用的选项如 -e, -x
三、参数扩展与操作

通过 ${} 对参数进行高级处理:

语法 作用 示例
${var:-default} 若 var 未设置/为空,则用 default echo ${NAME:-Guest} → 输出 Guest
${var:=default} 若 var 未设置/为空,则赋值为 default : ${PORT:=8080} → 设置 PORT=8080
${var:?error_msg} 若 var 未设置/为空,报错退出 ${DB_PASS:?密码未设置!}
${var:+alternate} 若 var 已设置,则用 alternate ${DEBUG:+调试模式} → DEBUG 非空时生效
${#var} 变量长度 NAME="Alice"; echo ${#NAME}5
${var:offset} 子串截取(从 offset 开始) TEXT="Hello"; echo ${TEXT:1}ello
${var:offset:length} 截取子串(指定长度) ${TEXT:1:3}ell
${var#pattern} 删除最短前缀匹配 FILE="/path/to/file.txt"; echo ${FILE#*/}path/to/file.txt
${var##pattern} 删除最长前缀匹配 ${FILE##*/}file.txt
${var%pattern} 删除最短后缀匹配 ${FILE%.*}/path/to/file
${var%%pattern} 删除最长后缀匹配 ${FILE%%.*}/path/to/file
${var/old/new} 单次替换 echo ${FILE/txt/pdf}/path/to/file.pdf
${var//old/new} 全局替换 echo ${PATH//\:/ } → 用空格分隔 PATH
${var^} / ${var^^} 首字母/全部大写 echo ${name^} → "Alice"
${var,} / ${var,,} 首字母/全部小写 echo ${NAME,,} → "alice"
四、选项处理进阶
1. getopts 内置命令(轻量级)

处理短选项(-a, -b value):

bash 复制代码
#!/bin/bash
while getopts "a:b:" opt; do  # 定义选项:a 无参,b 需参
  case $opt in
    a) echo "-a 参数: $OPTARG" ;;  # 错误:$OPTARG 仅在需参选项有效
    b) echo "-b 参数: $OPTARG" ;;  # 正确:$OPTARG 捕获值
    ?) echo "无效选项: -$OPTARG"; exit 1 ;;
  esac
done
shift $((OPTIND-1))  # 移除已处理选项,剩余作为参数
echo "剩余参数: $@"

运行:./script.sh -a test -b hello world

输出:

复制代码
-a 参数: ?        # 错误:$OPTARG 未定义(因 -a 未声明需参)
-b 参数: hello
剩余参数: world   # "test" 被忽略(因未在选项中定义)
2. getopt 外部命令(复杂选项)

支持长选项(--help):

bash 复制代码
#!/bin/bash
TEMP=$(getopt -o a::b: --long arg:,bravo: -n 'script.sh' -- "$@")
eval set -- "$TEMP"  # 重设位置参数

while true; do
  case "$1" in
    -a|--arg) ARG_A="$2"; shift 2 ;;  # 可选参数(::)
    -b|--bravo) ARG_B="$2"; shift 2 ;;
    --) shift; break ;;
    *) echo "内部错误!"; exit 1 ;;
  esac
done
echo "ARG_A=$ARG_A, ARG_B=$ARG_B, 剩余参数=$@"
五、参数传递实践技巧
1. 安全处理含空格参数
bash 复制代码
# 错误写法(参数被拆分)
cp $1 $2  # 若 $1="my file.txt" 会拆成两个参数

# 正确写法
cp "$1" "$2"  # 保留原始边界
2. 动态参数解析
bash 复制代码
# 遍历所有参数
for arg in "$@"; do
  if [[ $arg == --* ]]; then
    option="${arg#--}"  # 移除 "--" 前缀
  else
    values+=("$arg")    # 收集参数值
  fi
done
3. 参数默认值设置
bash 复制代码
# 方法1:位置参数扩展
output_file="${1:-result.log}"  # 若 $1 为空则用 result.log

# 方法2:条件判断
if [ -z "$1" ]; then
  input_file="default.in"
else
  input_file="$1"
fi
六、调试与验证参数
bash 复制代码
# 打印所有参数详情
echo "脚本名: $0"
echo "参数数: $#"
echo "所有参数: $@"
echo "参数列表:"
for i in $(seq 1 $#); do
  eval echo "\$$i = \${$i}"
done

# 检查必需参数
if [ $# -lt 2 ]; then
  echo "用法: $0 <input> <output>" >&2
  exit 1
fi

总结

类别 核心参数 应用场景
基础位置参数 $0, $1..$9, $@, $# 接收用户输入,循环处理
状态参数 $?, $$, $! 错误处理、进程管理
参数扩展 ${var:-def}, ${#var}, ${var//old/new} 安全赋值、字符串操作、默认值设置
选项解析 getopts, getopt 处理 -v/--verbose 类命令行开关

掌握这些参数机制,可编写出健壮、灵活的 Shell 脚本,适应从简单自动化到复杂运维任务的各种场景。

相关推荐
观音山保我别报错1 小时前
文件操作指南
linux·运维·服务器
JiMoKuangXiangQu1 小时前
Linux 内存管理 (6):slub 分配器
linux·内存管理·slab
NetInside_1 小时前
基于 Gartner 2025 报告:数字体验监测(DEM)核心价值与企业落地指南
运维·云原生
weixin_307779132 小时前
Jenkins 多分支流水线自动化引擎:GitHub Branch Source 插件完全指南
运维·架构·自动化·jenkins
_F_y2 小时前
Linux中gdb的使用
linux
谢某清心寡欲2 小时前
搭建Linux源码阅读环境
linux
孫治AllenSun2 小时前
【Doris】运维命令
运维·服务器·网络
我科绝伦(Huanhuan Zhou)2 小时前
Oracle控制文件、SCN与检查点机制深度解析及数据库初始化原理
运维·数据库·oracle
杨云龙UP3 小时前
从0到可落地:Oracle RMAN异地NFS备份标准脚本(多实例通用)
linux·运维·数据库·oracle