shell变量详解
Shell 脚本变量详解:脚本中的“记忆容器”
引言:变量——脚本的记忆单元
想象一下,你要帮妈妈记录她的烘焙配方。你会拿出一张纸,写上:
- 面粉 = 2杯
- 糖 = 1杯
- 烤箱温度 = 180度
这张纸记住了所有的配料和步骤,妈妈一看就明白。
在 Shell 脚本的世界里,变量就是这张“神奇的纸”。它是脚本的“记忆容器”,负责存储各种信息,比如名字、路径、数字,或者一条命令的执行结果。有了变量,脚本就能记住东西,变得更加聪明和灵活,能够处理复杂多变的任务。
本文将带你从零开始,全面了解 Shell 脚本中的变量,从如何“贴上标签”(定义变量)到如何“玩转标签”(高级应用),让你彻底掌握这个脚本编程的核心概念。
一、变量基础:贴标签与取东西
1.1 变量是什么?
在 Shell 中,变量本质上就是一个命名的存储空间。你可以把它想象成一个带标签的盒子:
- 标签名就是变量名。
- 盒子里放的东西就是变量的值。
Shell 中的变量非常随和,它把所有东西(数字、文本、路径)都当作字符串来存放,不需要你提前声明它要放什么类型的数据。
1.2 如何给盒子贴标签?(命名规则)
给变量起名(贴标签)要遵循一些简单的规则:
- ✅ 可以用的字符:字母(a-z, A-Z)、数字(0-9)、下划线(_)。
- ❌ 不能做的事:不能用数字开头。比如
1var是错误的,而var1是正确的。 - 🔠 大小写敏感:
MyVar和myvar是两个完全不同的变量。 - 💡 好习惯建议:
- 使用描述性的名字,比如用
backup_path而不是bp。 - 多个单词用下划线连接,如
student_name,这样更清晰。 - 对于整个脚本都需要的重要变量(全局变量),通常用大写字母,如
CONFIG_FILE,这是一种约定俗成的规范。
- 使用描述性的名字,比如用
1.3 如何往盒子里放东西?(定义与赋值)
把东西放进变量盒子(赋值)的语法非常简单:
name="Alice" # 在名为‘name’的盒子里放入“Alice”这个值 |
⚠️ 千万注意!:等号 = 的两边不能有任何空格!name = "Alice" 是错误的写法,Shell 会无法理解。
二、变量的作用域:私人物品与公共告示
变量不仅有自己的值,还有自己的“活动范围”,这就是作用域。
2.1 三种类型的变量
| 变量类型 | 作用范围 | 如何创建 | 例子 | 比喻 |
|---|---|---|---|---|
| 局部变量 | 当前脚本或Shell | var=value |
my_temp="hi" |
你日记本里的私密笔记 |
| 环境变量 | 当前及所有子进程 | export var=value |
export PATH="/usr/bin" |
小区公告栏的通知,人人都能看到 |
| 只读变量 | 无法修改 | readonly var=value |
readonly PI=3.14 |
刻在石头上的字,无法更改 |
2.2 管理环境变量
环境变量就像系统的全局设置,非常重要。
- 查看所有环境变量:使用
printenv或env命令。 - 让它永久生效:如果想让自己定义的环境变量每次登录都在,需要把
export VAR=value这行代码写到你的~/.bashrc或~/.bash_profile文件里,然后执行source ~/.bashrc让它立刻生效。 - 常用的系统环境变量:
echo "我是用户: $USER" # 输出当前用户名
echo "我家在: $HOME" # 输出当前用户的家目录路径
echo "我目前在: $PWD" # 输出当前所在的工作目录路径
三、特殊变量:脚本的内置工具箱
Shell 提供了一些内置的特殊变量,非常有用,它们像是脚本自带的工具箱。
3.1 传递参数:和脚本对话
当你运行脚本时在后面加参数,比如 ./script.sh arg1 arg2,这些参数怎么在脚本里拿到呢?
| 特殊变量 | 含义与用途 | 示例 |
|---|---|---|
$0 |
脚本自己的名字 | echo "正在运行: $0" |
$1-$9 |
第1个到第9个参数 | echo "第一个参数是: $1" |
${10} |
第10个参数(以此类推) | echo "第十个参数: ${10}" 必须加花括号 |
$# |
一共传了多少个参数 | echo "你一共给了 $# 个参数" |
3.2 $@ 和 $*:处理所有参数
它们都代表所有参数,但在细节上有微妙且重要的区别:
# 假设脚本接收三个参数:arg1 arg2 arg3 |
3.3 进程状态变量
| 变量 | 含义与用途 | 示例 |
|---|---|---|
$$ |
当前脚本运行的进程ID(PID) | echo "这个脚本的PID是: $$" |
$! |
最后一个在后台运行的进程PID | echo "后台任务的PID是: $!" |
$? |
上一条命令的执行结果状态码 | ls /tmp; echo "上条命令结果: $?" 0表示成功,非0表示出错 |
四、高级技巧:玩转你的变量
4.1 处理字符串
变量里存放的大部分是字符串,Shell 提供了一些方法来操作它们。
my_str="Hello World" |
4.2 设置默认值
处理可能不存在的变量时,这个功能非常实用。
# 如果变量 VAR 没设置或者为空,就使用后面的默认值,但不会改变 VAR 本身 |
4.3 进行数学计算
虽然变量存的是字符串,但我们仍然可以做数学计算。
a=10 |
五、实战演练:看看变量如何大显身手
5.1 案例一:自动生成带时间的日志文件名
|
5.2 案例二:安全地读取用户输入
|
5.3 案例三:检查脚本参数是否提供
|
六、最佳实践与避坑指南
引号的重要性:
- 赋值时不要加引号:
var=value - 使用变量时推荐加双引号:
echo "$var"— 这样可以避免变量值中有空格时被拆开,导致意外错误。 - 值里有空格就必须加引号:
file_path="/path/with spaces/file.txt"
- 赋值时不要加引号:
防止变量未定义的灾难:
在脚本开头加上set -u。这样一旦你使用了未赋值的变量,脚本会立即报错并停止,而不是默默地继续执行下去。
set -u # 开启“未定义变量报错”模式
echo "$undefined_var" # 这行会导致脚本报错退出
echo "这行不会被执行到"理解数字的限制:
Shell 变量本质是字符串,所以数学计算有其局限性。记住:- 它主要进行整数运算。
- 需要复杂的小数计算时,请调用
bc或awk这些更强大的工具。
总结
变量是 Shell 脚本的基石和记忆核心。它从简单的存储和取值出发,通过作用域管理影响范围,通过特殊变量与脚本外部交互、感知自身状态,再通过字符串操作、默认值设置、数学运算等高级技巧变得无比强大。
从编写一个简单的日志脚本,到一个需要处理复杂用户输入和参数的系统工具,深刻理解并熟练运用变量是成功的关键。希望这篇详解能成为你 Shell 脚本之旅上的得力助手!
