0%

位置参数变量

Shell 位置参数变量:处理命令行传参的实用指南

在 Shell 脚本中,位置参数变量用于接收和处理命令行传入的参数,是实现脚本灵活性和复用性的关键。无论是简单的参数传递还是复杂的批量处理,掌握位置参数变量都能高效完成任务。以下是详细解析和示例。

基础位置参数变量

1. $n:按序号获取参数

  • $0:表示脚本本身的名称(包含路径时显示完整路径)。
  • $1~$9:表示第 1 到第 9 个参数。
  • ${10}及以上:10 个以上的参数需用大括号包裹(如${10}${11})。

示例params.sh 脚本

1
2
3
4
5
#!/bin/bash
echo "脚本名称:$0"
echo "第1个参数:$1"
echo "第2个参数:$2"
echo "第10个参数:${10}"

执行脚本:

1
sh params.sh a b c d e f g h i j k

输出:

1
2
3
4
脚本名称:params.sh
第1个参数:a
第2个参数:b
第10个参数:j

2. $#:获取参数总数

  • 表示命令行传入的参数总个数(不包含脚本名称$0)。

示例:统计参数个数

1
2
3
4
5
6
7
8
#!/bin/bash
echo "参数总数:$# 个"

# 判断参数是否足够
if [ $# -lt 2 ]; then
echo "错误:至少需要传入2个参数!"
exit 1 # 非0退出表示执行失败
fi

执行脚本:

1
2
sh count_params.sh 1 2 3
# 输出:参数总数:3 个

批量处理所有参数

1. $*$@:获取所有参数

两者都表示命令行中的所有参数,但处理方式不同:

  • $*:将所有参数视为一个整体字符串(用空格分隔)。
  • $@:将每个参数视为独立的字符串(保留参数边界)。

示例:对比 $*$@

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
echo "使用 \$* 遍历:"
for param in "$*"; do
echo "- $param"
done

echo -e "\n使用 \$@ 遍历:"
for param in "$@"; do
echo "- $param"
done

执行脚本:

1
sh all_params.sh a "b c" d

输出:

1
2
3
4
5
6
7
使用 $* 遍历:
- a b c d # 所有参数被合并为一个字符串

使用 $@ 遍历:
- a # 保持原参数结构("b c"作为一个参数)
- b c
- d

结论:遍历参数时优先使用 $@,能正确保留包含空格的参数。

2. 截取部分参数

通过 ${@:起点}${@:起点:个数} 可截取部分参数:

  • ${@:n}:从第n个参数开始,获取后面所有参数(n从 1 开始)。
  • ${@:n:m}:从第n个参数开始,获取m个参数。

示例:截取参数

1
2
3
4
#!/bin/bash
echo "所有参数:$@"
echo "从第2个参数开始:${@:2}"
echo "从第2个参数开始,取2个:${@:2:2}"

执行脚本:

1
sh slice_params.sh 10 20 30 40 50

输出:

1
2
3
所有参数:10 20 30 40 50
从第2个参数开始:20 30 40 50
从第2个参数开始,取2个:20 30

特殊变量 $?:获取执行状态

$? 用于获取上一条命令的退出状态码

  • 0:命令执行成功。
  • 非 0:命令执行失败(不同数值表示不同错误类型)。

示例:检查命令执行结果

1
2
3
4
5
6
7
8
9
#!/bin/bash
# 尝试创建目录
mkdir test_dir

if [ $? -eq 0 ]; then
echo "目录创建成功!"
else
echo "目录创建失败!"
fi

执行脚本:

1
2
3
sh check_status.sh
# 首次执行输出:目录创建成功!
# 再次执行(目录已存在)输出:目录创建失败!

实际应用案例

1. 简单计算器脚本

接收两个数字和一个运算符,计算结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
# 文件名:calculator.sh

if [ $# -ne 3 ]; then
echo "用法:$0 数字1 运算符 数字2"
echo "示例:$0 10 + 20"
exit 1
fi

num1=$1
op=$2
num2=$3

case $op in
+) result=$((num1 + num2)) ;;
-) result=$((num1 - num2)) ;;
*) echo "不支持的运算符:$op"; exit 1 ;;
esac

echo "$num1 $op $num2 = $result"

执行脚本:

1
2
sh calculator.sh 15 + 35
# 输出:15 + 35 = 50

2. 批量文件重命名

将指定目录下的所有.txt文件添加前缀(第一个参数为前缀,第二个参数为目录):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
# 文件名:rename_files.sh

prefix=$1
dir=${2:-.} # 默认为当前目录

# 校验参数
if [ -z "$prefix" ]; then
echo "用法:$0 前缀 [目录]"
exit 1
fi

# 遍历目录下的txt文件
for file in "$dir"/*.txt; do
# 跳过不存在的文件(避免通配符未匹配的情况)
[ -f "$file" ] || continue

# 获取文件名(不含路径)
filename=$(basename "$file")
# 重命名
mv "$file" "$dir/$prefix$filename"
echo "已重命名:$filename$prefix$filename"
done

执行脚本:

1
2
sh rename_files.sh "2025_" ./docs
# 输出:已重命名:readme.txt → 2025_readme.txt

注意事项

  1. 参数边界处理
    脚本中应检查参数个数是否符合要求(如用 if [ $# -lt N ]),避免因参数缺失导致错误。
  2. 特殊字符处理
    若参数包含空格、星号(*)等特殊字符,传入时需用双引号包裹(如 sh script.sh "hello world")。
  3. 位置参数的偏移
    可通过 shift 命令左移参数(如 shift 2 表示丢弃前 2 个参数,$3 变为新的 $1),适合处理不定长参数

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10