【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 天前
LVS负载均衡
服务器·负载均衡·lvs
小成202303202651 天前
Linux高级02
linux·开发语言
mounter6251 天前
【硬核前沿】CXL 深度解析:重塑数据中心架构的“高速公路”,Linux 内核如何应对挑战?-- CXL 协议详解与 LSF/MM 最新动态
linux·服务器·网络·架构·kernel
++==1 天前
Linux 进程间通信与线程同步技术详解:IPC 机制、线程 API、同步工具与经典同步问题
linux
特长腿特长1 天前
centos、ubantu系列机的用户和用户组的结构是什么?具体怎么配置?用户组权限怎么使用?这篇文章持续更新,帮助你复习linux的基础知识
linux·运维·centos
zzzyyy5381 天前
Linux环境变量
linux·运维·服务器
pluvium271 天前
记对 xonsh shell 的使用, 脚本编写, 迁移及调优
linux·python·shell·xonsh
无级程序员1 天前
centos7 安装 llvm-toolset-7-clang出错的问题解决
linux·centos
kebeiovo1 天前
atomic原子操作实现无锁队列
服务器·c++
赛博云推-Twitter热门霸屏工具1 天前
Twitter运营完整流程:从0到引流获客全流程拆解(2026)
运维·安全·自动化·媒体·twitter