Shell 传递参数

《Shell 传递参数》

🧾 学习目标

  1. 掌握 Shell 脚本中如何接收和处理用户传入的参数。
  2. 理解位置参数($1, $2, ...)、特殊变量($#, $@, $*)等核心概念。
  3. 学会使用 getopts 实现带选项的命令行参数解析,提升脚本灵活性与专业性。
  4. 能在阿里云 Ubuntu ECS 上编写支持参数传递的自动化脚本,用于部署、日志分析、服务管理等场景。
  5. 理解参数校验、默认值设置、错误提示等高级技巧。

🧠 核心重点(表格提炼)

内容 示例 说明
参数获取 $1, $2, ..., ${10} 获取第 n 个参数
参数个数 $# 表示传入参数的数量
所有参数(字符串形式) $* 将所有参数作为一个整体字符串
所有参数(数组形式) $@ 每个参数作为独立项,常用于循环
参数遍历 for arg in "$@"; do ... done 遍历所有参数
命令行选项解析 getopts 支持 -a, -b value 等格式
默认值设置 ${var:-default} 若未定义则用默认值
参数校验 [ -z "$1" ] && echo "缺少参数" 防止空参数或非法输入

🔍 详细讲解

1. Shell 中的参数是什么?🧐

在执行 Shell 脚本时,我们可以通过命令行给脚本传入额外信息,这些信息就被称为“参数”或“命令行参数”。

📌 为什么重要?

  • 让脚本具备动态行为,不再是“死代码”。
  • 提高脚本的通用性和可复用性。
  • 是构建自动化工具、运维脚本、部署脚本的基础。

📌 举例:

./backup.sh /etc 7
  • /etc 是第一个参数(备份目录)
  • 7 是第二个参数(保留天数)

2. Shell 参数的基本使用 📝

✅ 1. 获取参数(位置参数)

变量 含义
$0 当前脚本名称
$1 ~ $9 第1~第9个参数
${10} 第10个及以上参数(需用 {} 包裹)

📌 示例:

#!/bin/bash
echo "脚本名:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"

📌 运行:

./script.sh hello world

📌 输出:

脚本名:./script.sh
第一个参数:hello
第二个参数:world

✅ 2. 获取参数个数 $#

echo "共 $# 个参数"

📌 用途:

  • 判断是否传入了足够的参数
  • 控制脚本逻辑分支

✅ 3. 获取所有参数 $*$@

变量 特点
$* 把所有参数当作一个整体字符串
$@ 把每个参数当作独立元素,更适合遍历

📌 示例:

for arg in "$@"; do
    echo "参数:$arg"
done

📌 运行:

./script.sh apple banana cherry

📌 输出:

参数:apple
参数:banana
参数:cherry

3. 实战案例:ECS 上的参数化脚本应用 🛠️

场景一:编写一个自动清理日志文件的脚本 🗂️

你想根据传入的目录和保留天数,自动删除旧日志。

✅ 示例脚本 log_cleaner.sh

#!/bin/bash
# Usage: ./log_cleaner.sh <目录路径> <保留天数>
dir=${1:-/var/log}
days=${2:-7}

find "$dir" -type f -mtime +"$days" -exec rm -f {} \;
echo "✅ 已清理 $days 天前的日志文件(目录:$dir)"

📌 运行方式:

chmod +x log_cleaner.sh
./log_cleaner.sh /var/log 30   # 清理 30 天前的日志
./log_cleaner.sh              # 使用默认值(/var/log,7 天)

场景二:使用 getopts 解析带选项的命令行参数 🎛️

你希望你的脚本支持像 ls -ltar -cvf 这样的命令风格。

✅ 示例脚本 backup.sh

#!/bin/bash
# Usage: ./backup.sh -d <目录> -k <天数>

while getopts "d:k:" opt; do
  case $opt in
    d) dir="$OPTARG";;
    k) days="$OPTARG";;
    *) echo "Usage: $0 -d <目录> -k <天数>"; exit 1;;
  esac
done

dir=${dir:-/var/log}
days=${days:-7}

find "$dir" -type f -mtime +"$days" -exec rm -f {} \;
echo "✅ 已清理 $days 天前的文件(目录:$dir)"

📌 运行方式:

./backup.sh -d /tmp -k 5
./backup.sh -d /home/ubuntu

📌 优点:

  • 更加规范和灵活
  • 支持多个选项
  • 易于扩展(如增加 -v 详细模式)

场景三:参数校验与错误提示 ⚠️

你想确保用户传入了必要的参数,避免脚本出错。

✅ 示例代码:

if [ -z "$1" ]; then
    echo "❌ 错误:必须传入一个目录路径"
    echo "Usage: $0 <目录>"
    exit 1
fi

📌 输出示例:

❌ 错误:必须传入一个目录路径
Usage: ./script.sh <目录>

🧰 小贴士(进阶技巧)🔖

技巧 说明
shift 移动参数位置,便于逐个处理
eval set -- "$ARGS" 结合 getopt 使用更复杂参数
OPTARG getopts 中当前参数的值
OPTIND 当前处理到的位置
${!#} 获取最后一个参数
declare -A args 使用关联数组保存参数(bash 4+)

📌 注意事项与安全建议

项目 建议
所有参数引用都应加双引号 "$1",防止空格问题
对关键参数做校验 如是否存在、是否为数字等
不要直接拼接参数执行命令 防止命令注入攻击
设置合理的默认值 提升用户体验
使用 exit 终止非法调用 避免脚本继续执行导致错误
日志记录参数内容(可选) 便于调试和审计

🧩 附录:Shell 参数处理模板(推荐使用)

#!/bin/bash
# 脚本名称:deploy.sh
# 功能描述:根据传入参数部署应用
# 作者:Linux 专家
# 日期:2025-06-17

usage() {
    echo "Usage: $0 -e <环境> [-r <版本>] [-v]"
    echo "  -e 环境(dev/prod/staging)"
    echo "  -r 版本号(可选)"
    echo "  -v 启用详细模式"
    exit 1
}

VERBOSE=0
ENV=""
VERSION="latest"

while getopts "e:r:v" opt; do
  case $opt in
    e) ENV="$OPTARG";;
    r) VERSION="$OPTARG";;
    v) VERBOSE=1;;
    *) usage ;;
  esac
done

if [ -z "$ENV" ]; then
    echo "❌ 必须指定环境"
    usage
fi

[ "$VERBOSE" -eq 1 ] && echo "正在部署到 $ENV 环境,版本:$VERSION"
# 执行部署逻辑...

📌 运行方式:

./deploy.sh -e dev
./deploy.sh -e prod -r v1.0.0 -v

🎯 总结一句话:

“Shell 参数就像是一封信✉️ —— 它能让你写的脚本更聪明、更灵活、更有用,是你通往 Linux 自动化高手的必经之路!”

是否继续下一章?我将继续输出:

  • 《Shell 条件判断与流程控制》⚙️
  • 《Shell 循环结构详解》🔁
  • 《Shell 函数与模块化编程》📦

请告诉我你想深入的方向吧!🚀

posted @ 2023-04-02 21:17  红尘过客2022  阅读(153)  评论(0)    收藏  举报