【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 脚本,适应从简单自动化到复杂运维任务的各种场景。

相关推荐
研华嵌入式12 小时前
Ubuntu 20.04 停止支持怎么办?
linux·运维·ubuntu
是阿威啊13 小时前
【第二站】本地hadoop集群配置yarn模式
大数据·linux·hadoop·yarn
野熊佩骑13 小时前
一文读懂运维监控之 Ubuntu22.04安装部署Zabbix监控
linux·运维·服务器·网络·ubuntu·zabbix·database
双层吉士憨包13 小时前
Claude账号共享教程分享
运维·服务器
大聪明-PLUS13 小时前
了解 Docker:镜像是如何创建的
linux·嵌入式·arm·smarc
lllsure14 小时前
Linux 日志管理
linux·运维·服务器
yewq-cn14 小时前
自动更新 Docker 镜像
运维·docker·容器
haluhalu.14 小时前
Linux系统下进程池设计与实现详解
linux·运维·服务器
m0_5374734914 小时前
Nginx 生产环境平滑升级实战:从 1.24.0 到 1.28.0 的零宕机操作全记录
运维·nginx
虹梦未来14 小时前
【运维】Ubuntu2404使用新风格更新镜像源
运维·服务器