Shell脚本-变量的分类
一、前言
在 Linux 系统中,Shell 脚本是自动化运维、系统管理、任务调度的重要工具。而变量作为 Shell 脚本中最基本的组成部分之一,掌握其分类和使用方式,是编写高效、可维护脚本的前提。
本文将系统性地介绍 Shell 脚本中变量的分类,包括:用户自定义变量、环境变量、位置变量、特殊变量四大类,并结合大量实际示例帮助你深入理解每种变量的特点与使用场景。
二、Shell 变量概述
在 Shell 中,变量是用来存储数据的命名标识符。它不需要声明类型,值可以是字符串、数字或命令执行结果。
基本语法:
variable_name=value
⚠️ 注意:等号
=
两边不能有空格!
例如:
name="Alice"
age=25
三、Shell 变量的四大分类
1. 用户自定义变量(Local Variables)
✅ 定义:
由用户在脚本或命令行中手动定义的变量,仅在当前 Shell 会话中有效,不会被子进程继承。
✅ 特点:
- 作用域:当前 Shell 进程
- 不会传递给子 Shell 或脚本
- 通常用于脚本内部逻辑处理
✅ 示例:
#!/bin/bash
my_var="Hello World"
echo $my_var
执行结果:
Hello World
但如果在子 Shell 中调用该变量:
bash -c 'echo $my_var' # 输出为空,因为 my_var 不是环境变量
✅ 如何查看用户变量?
使用 set
命令可以查看当前 Shell 中所有变量(包括局部变量、环境变量、函数等):
set | grep my_var
2. 环境变量(Environment Variables)
✅ 定义:
环境变量是在整个 Shell 环境中生效的变量,可以被当前进程及其子进程继承。常用于配置系统行为、路径、语言等。
✅ 设置方式:
使用 export
命令将局部变量导出为环境变量:
export MY_NAME="Bob"
或分两步:
MY_NAME="Bob"
export MY_NAME
✅ 常见系统环境变量:
变量名 | 含义 |
---|---|
HOME | 用户主目录路径 |
PATH | 可执行文件搜索路径 |
SHELL | 当前使用的 Shell 类型 |
USER | 当前用户名 |
PWD | 当前工作目录 |
LANG | 系统语言设置 |
✅ 查看环境变量:
printenv # 查看所有环境变量
printenv PATH # 查看 PATH 的值
echo $HOME # 输出用户主目录
✅ 自定义环境变量持久化
要让环境变量在每次登录时自动生效,需写入配置文件:
- 当前用户:
~/.bashrc
或~/.profile
- 所有用户:
/etc/environment
或/etc/profile
例如,在 ~/.bashrc
中添加:
export MY_APP_HOME="/opt/myapp"
然后执行:
source ~/.bashrc
3. 位置变量(Positional Parameters)
✅ 定义:
位置变量用于获取传递给 Shell 脚本或函数的命令行参数。它们是 Shell 内置的特殊变量,以 $1
, $2
, ..., $9
, ${10}
形式表示。
✅ 常用位置变量:
变量 | 含义 |
---|---|
$0 | 脚本名称 |
$1 ~ $9 | 第1到第9个参数 |
${10} | 第10个参数(必须用花括号) |
$# | 传递的参数个数 |
$* | 所有参数作为一个字符串 |
$@ | 所有参数作为独立字符串数组 |
✅ 实例演示
创建脚本 test.sh
:
#!/bin/bash
echo "脚本名称: $0"
echo "第一个参数: $1"
echo "第二个参数: $2"
echo "参数总数: $#"
echo "所有参数(\$*): $*"
echo "所有参数(\$@): $@"
运行:
bash test.sh apple banana cherry
输出:
脚本名称: test.sh
第一个参数: apple
第二个参数: banana
参数总数: 3
所有参数($*): apple banana cherry
所有参数($@): apple banana cherry
💡 区别:
$*
将所有参数视为一个整体,而$@
保持每个参数独立,在循环中更推荐使用"$@"
。
✅ 遍历参数示例:
for arg in "$@"; doecho "参数: $arg"
done
4. 特殊变量(Special Variables)
✅ 定义:
Shell 提供了一些内置的特殊变量,用于获取脚本运行状态、进程信息等,不能手动赋值。
✅ 常见特殊变量列表:
变量 | 含义 |
---|---|
$$ | 当前 Shell 进程的 PID(进程 ID) |
$! | 最后一个后台运行进程的 PID |
$? | 上一个命令的退出状态码(0 表示成功) |
$0 | 脚本名(也属于位置变量) |
$_ | 上一个命令的最后一个参数 |
✅ 示例说明:
#!/bin/bashecho "当前脚本 PID: $$"sleep 10 &
echo "后台进程 PID: $!"echo "脚本名称: $0"ls /nonexistent
echo "上一个命令状态: $?" # 输出非0,表示失败touch testfile
cp testfile backup.txt
echo "上一个命令最后一个参数: $_" # 输出 backup.txt
💡 应用场景:
$?
常用于判断命令是否执行成功$$
可用于生成唯一的临时文件名,如/tmp/myapp.$$
四、变量作用域与继承关系总结
变量类型 | 是否可被子进程继承 | 设置方式 | 查看命令 |
---|---|---|---|
用户自定义变量 | ❌ 否 | var=value | set |
环境变量 | ✅ 是 | export var=value | printenv 或 env |
位置变量 | ⚠️ 仅在脚本/函数内有效 | 命令行传参 | $1 , $2 ... |
特殊变量 | ❌(只读) | 内置 | 直接引用 |
五、常见问题与注意事项
❗ 1. 变量名与关键字冲突
避免使用 Shell 关键字作为变量名,如 if
, for
, do
, test
等。
❗ 2. 引号使用不当
name="John Doe"
echo $name # 可能出错(如果中间有空格)
echo "$name" # 推荐:使用双引号包裹
❗ 3. 未定义变量导致错误
开启 set -u
可在使用未定义变量时报错:
set -u
echo $undefined_var # 报错并退出
❗ 4. $*
与 $@
的区别
在双引号中:
"$*"
→"arg1 arg2 arg3"
"$@"
→"arg1" "arg2" "arg3"
推荐在遍历时使用 "$@"
保持参数独立性。
六、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!