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

相关推荐
龙仔7253 分钟前
ZLMediaKit 日志按日期切割与自动清理方案
运维·服务器·日志切割·自动删除
XRJ040618xrj5 分钟前
如何在Linux虚拟环境下创建配置网络脚本
linux·网络·php
电化学仪器白超8 分钟前
计量室自动化系统技术文档编制与动态更新说明
运维·python·嵌入式硬件·自动化
这儿有一堆花8 分钟前
SSH 协议的加密与认证原理
运维·网络·ssh
Exquisite.8 分钟前
云原生高级课前置复习(2)
linux·云原生
码猩9 分钟前
自用centos9离线安装n8n非docker部署本版
运维·docker·容器
m0_7373025812 分钟前
云原生国产化,联通云CSK Turbo重构安全底座
服务器
Apex Predator13 分钟前
jenkins备份与恢复
运维·jenkins
FreeSoar118 分钟前
Rocky Linux 10.1 64位安装Firebird3.0
linux·运维·服务器
小趴菜不能喝19 分钟前
服务器推送事件SSE
运维·服务器