3.Shell脚本修炼手册之---Shell 变量基础知识
3. Shell 变量基础知识
文章目录
- 3. Shell 变量基础知识
- 3.1 什么是 Shell 变量
- 3.1.1 什么是变量
- 3.1.2 Shell 变量的特性
- 3.1.3 变量类型
- 3.2 环境变量
- 环境变量的特点:
- 3.2.1 设置环境变量
- 1. 临时设置环境变量
- 2. 永久设置环境变量
- 3. 设置登录后提示信息(实验)
- 3.2.2 显示与取消环境变量
- 3.2.3 环境变量初始化顺序(登录 Shell vs 非登录 Shell)
- 3.2.4 环境变量小结
- 3.3 普通变量
- 3.3.1 普通变量的定义方式
- 3.3.2 变量名和值的要求
- 3.3.3 普通变量定义及输出实验
- 3.3.4 把命令结果赋值给变量(实验)
- 3.4 变量定义技巧总结
3.1 什么是 Shell 变量
3.1.1 什么是变量
简单说,变量就像一个贴了标签的 “盒子”—— 用一个固定字符串(只能包含字母、数字和下划线,且不能以数字开头)作为 “标签”,用来存放更复杂的内容(比如其他变量、文件路径、一段文字等)。
这个 “盒子” 的作用是临时存储数据(数据存在内存中),需要时通过 “标签”(变量名)就能快速取出里面的内容。用变量的好处很直观:让程序写起来更方便,比如重复使用的内容只需定义一次,后续改起来也只需改一处。
示例:定义和使用变量
# 定义变量:给"标签"username贴在装着"bq"的盒子上
# 注意:等号两边不能有空格,这是Shell的语法规定
[bq@shell ~]$ username="bq"# 打印变量的值:用$+变量名,相当于"打开标签为username的盒子"
[bq@shell ~]$ echo $username
bq # 输出结果:盒子里的内容"bq"
小贴士:给变量赋值时,值最好用双引号括起来,尤其是值里有空格的时候(比如name="Zhang San"
),避免解析错误。
3.1.2 Shell 变量的特性
和 Java、C 等语言不同,bash Shell 默认不区分变量类型—— 不管你存的是数字(123)、字符串(“abc”)还是小数(3.14),它都当字符串处理。
如果确实需要指定类型(比如强制为整数),可以用declare
命令,但日常使用基本用不上,记住 “默认全是字符串” 就行。
3.1.3 变量类型
按作用范围分,变量有两类:
- 全局变量:创建它的 Shell 和它的 “子 Shell”(比如 Shell 中启动的脚本、新进程)都能使用。
类比:家里的冰箱,全家人(包括孩子)都能打开用。 - 局部变量:只能在创建它的 Shell 函数或脚本里用,出了这个范围就无效。
类比:个人的抽屉,只有自己能打开。
按是否用户自定义分,变量也有两类:
- 普通变量:开发者自己定义的变量,比如上面例子中的
username
。 - 环境变量:定义 Shell 运行环境的变量(比如系统默认的
PATH
—— 命令存放路径),分 “系统自带” 和 “用户自定义” 两种。
3.2 环境变量
环境变量是用export
命令导出的变量,作用是 “给 Shell 设定运行规则”—— 比如告诉 Shell"命令存放在哪些路径"(PATH
)、“当前用户的家目录在哪”(HOME
)。
所有环境变量都是全局变量,能被 Shell 的子进程(比如编辑器、脚本)继承。
环境变量的特点:
- 按规范,名字通常全大写(比如
PATH
、USER
)。 - 临时设置:在命令行直接定义,退出 Shell 后就失效。
- 永久生效:写进配置文件(比如用户家目录的
.bashrc
,或全局的/etc/bashrc
),每次登录自动加载。
常见环境变量举例:
变量名 | 作用 |
---|---|
HOME | 当前用户的家目录(比如/home/bq ) |
PATH | 命令搜索路径(输入命令时,Shell 会在这些路径里找可执行文件) |
USER | 当前登录的用户名(比如bq ) |
PWD | 当前所在目录的路径 |
LANG | 系统语言设置(比如zh_CN.UTF-8 ) |
查看变量的命令:
set
:显示所有变量(全局 + 局部)。env
:只显示全局变量(环境变量)。declare
:显示所有变量、函数、整数及导出的变量。
3.2.1 设置环境变量
1. 临时设置环境变量
用export
或declare -x
命令,三种写法效果一样:
# 写法1:直接定义并导出
export NAME="bq" # 定义变量NAME=“bq”,同时导出为环境变量# 写法2:先定义,再导出
NAME="bq"
export NAME # 把已定义的变量NAME导出为环境变量# 写法3:用declare -x(-x表示导出)
declare -x NAME="bq" # 效果和export一样
验证效果:
执行echo $NAME
会输出bq
,执行env | grep NAME
能看到NAME=bq
(说明已成为环境变量)。
2. 永久设置环境变量
要让环境变量重启后仍有效,需写进配置文件,推荐路径:
- 用户级:
~/.bashrc
(当前用户专用,优先推荐)。 - 系统级:
/etc/bashrc
(所有用户共用)。
操作步骤:
# 以用户级为例,用vim编辑~/.bashrc
[bq@shell ~]$ vim ~/.bashrc# 在文件末尾添加环境变量(比如设置一个自定义变量MY_PATH)
export MY_PATH="/home/bq/scripts"# 保存退出后,让配置立即生效(不用重启Shell)
[bq@shell ~]$ source ~/.bashrc # 或 . ~/.bashrc# 验证:查看变量是否生效
[bq@shell ~]$ echo $MY_PATH
/home/bq/scripts # 输出结果,说明设置成功
3. 设置登录后提示信息(实验)
实验流程:
- 方法 1:修改
/etc/motd
文件设置提示。 - 方法 2:在
/etc/profile.d/
目录下添加脚本设置提示。 - 验证两种方法的效果。
方法 1:修改 /etc/motd
# 编辑/etc/motd(需要root权限,用sudo)
[bq@shell ~]$ sudo vim /etc/motd# 在文件中写入提示内容
welcome to bq linux Shell training. # 这行是要显示的提示语# 保存退出后,重新登录(比如断开SSH再连接)
# 登录后会看到以下内容:
Welcome to bq linux Shell training. # 我们设置的提示
Last login: Wed Aug 20 18:51:11 2025 # 系统默认的上次登录信息
方法 2:在 /etc/profile.d/ 添加脚本
# 在/etc/profile.d/目录下创建一个.sh脚本(文件名自定义,比如bq.sh)
[bq@shell ~]$ sudo vim /etc/profile.d/bq.sh# 写入提示命令(echo后面跟要显示的内容)
echo "Welcome to bq linux Shell training.(来自profile.d脚本)"# 保存退出,无需加执行权限(系统会自动加载该目录下的脚本)
# 重新登录后效果:
Welcome to bq linux Shell training.(来自profile.d脚本)
Last login: Wed Aug 20 18:53:22 2025
补充知识:
- 登录前的提示(比如 SSH 连接时输入密码前看到的内容)由
/etc/issue
文件控制。 - 登录后显示的 “上次登录时间” 由 SSH 服务控制,配置文件是
/etc/ssh/sshd_config
,默认开启(PrintLastLog yes
)。
3.2.2 显示与取消环境变量
-
显示变量:用
echo $变量名
或printf "%s\n" $变量名
。
示例:echo $HOME
输出/home/bq
。 -
取消变量:用
unset 变量名
(注意不加 $)。
示例:[bq@shell ~]$ export TEST="hello" # 定义环境变量TEST [bq@shell ~]$ echo $TEST hello # 变量有效 [bq@shell ~]$ unset TEST # 取消变量 [bq@shell ~]$ echo $TEST# 输出为空,变量已失效
3.2.3 环境变量初始化顺序(登录 Shell vs 非登录 Shell)
当你启动 Shell 时,它会自动加载一系列配置文件来初始化环境变量,加载顺序取决于 Shell 的启动方式:
1. 登录 Shell(比如通过 SSH 登录、本地终端输入账号密码)
加载顺序:
/etc/profile
(系统全局配置) → /etc/profile.d/
下的脚本 → ~/.bash_profile
(用户级配置) → ~/.bashrc
(用户级非登录配置) → /etc/bashrc
(系统全局非登录配置)
2. 非登录 Shell(比如在已登录的终端里输入bash
启动的新 Shell)
加载顺序:
~/.bashrc
→ /etc/bashrc
→ /etc/profile.d/
下的脚本
为什么要了解这个?
如果你设置的环境变量在新 Shell 里不生效,可能是放错了配置文件。比如想让变量在非登录 Shell 里生效,就别放在/etc/profile
或~/.bash_profile
,而要放在~/.bashrc
或/etc/bashrc
。
3.2.4 环境变量小结
- 名字通常全大写(比如
PATH
、USER
)。 - 能在当前 Shell 和它的子 Shell 中使用。
- 用
export
定义,env
命令可查看所有环境变量。 - 用
$变量名
调用,unset 变量名
删除。 - 定时任务(crond)中要用的环境变量,最好在脚本里重新定义(避免依赖系统配置)。
- 永久生效需写入配置文件(推荐
~/.bashrc
或/etc/bashrc
)。
3.3 普通变量
普通变量是 “局部” 的,只在创建它的 Shell 或脚本中有效,一旦退出 Shell 或启动子进程,变量就失效了。
3.3.1 普通变量的定义方式
有三种赋值方式,核心区别在 “是否解析变量 / 命令”:
变量名=value
(不加引号)变量名='value'
(单引号)变量名="value"
(双引号)
3.3.2 变量名和值的要求
- 变量名:只能包含字母、数字、下划线,且必须以字母或下划线开头(比如
user1
、_age
合法,1user
、user-name
不合法)。 - 变量值:是否加引号、加哪种引号,决定了 Shell 是否解析值里的变量或命令。
3.3.3 普通变量定义及输出实验
实验流程:
- 用三种方式定义变量(不加引号、单引号、双引号),值中包含其他变量。
- 打印变量,观察输出差异。
- 总结三种引号的作用。
实验步骤及结果:
# 先定义一个基础变量,供后续引用
[bq@shell ~]$ base="10.1.8.10"# 1. 不加引号定义变量a
[bq@shell ~]$ a=($base-$base) # 值里引用了$base
[bq@shell ~]$ echo "a=$a"
a=10.1.8.10-10.1.8.10 # 结果:$base被解析成了实际值# 2. 单引号定义变量b
[bq@shell ~]$ b='$base-$base' # 单引号包裹值
[bq@shell ~]$ echo "b=$b"
b=$base-$base # 结果:$base没被解析,原样输出# 3. 双引号定义变量c
[bq@shell ~]$ c="$base-$base" # 双引号包裹值
[bq@shell ~]$ echo "c=$c"
c=10.1.8.10-10.1.8.10 # 结果:$base被解析成了实际值
三种方式的区别总结:
赋值方式 | 特点 | 适用场景 |
---|---|---|
不加引号 | 解析变量和命令,但值中不能有空格 | 简单字符串(如数字、无空格路径) |
单引号' ' | 不解析任何变量和命令,原样输出 | 纯字符串(不需要替换变量的场景) |
双引号" " | 解析变量和命令,支持值中包含空格 | 带变量、空格的字符串(最常用) |
3.3.4 把命令结果赋值给变量(实验)
实验流程:
- 用两种方式(反引号、$())将命令结果赋值给变量。
- 打印变量验证结果。
- 比较两种方式的优劣。
实验步骤及结果:
# 1. 反引号` `(不推荐,易与单引号混淆)
[bq@shell ~]$ cmd1=`ls` # 把ls命令的结果(当前目录文件)赋值给cmd1
[bq@shell ~]$ echo "cmd1=$cmd1"
cmd1=script.sh # 输出当前目录的文件(假设只有script.sh)# 2. $()(推荐,清晰易读)
[bq@shell ~]$ cmd2=$(pwd) # 把pwd命令的结果(当前路径)赋值给cmd2
[bq@shell ~]$ echo "cmd2=$cmd2"
cmd2=/home/bq # 输出当前路径# 3. 嵌套命令示例($()更方便)
[bq@shell ~]$ today=$(date +%A) # date +%A表示获取星期几
[bq@shell ~]$ echo "今天是$today"
今天是Friday # 假设当天是周五
结论:推荐用$()
,尤其是命令嵌套时(比如$(ls $(pwd))
),比反引号更直观,不容易出错。
3.4 变量定义技巧总结
- 变量名规范:
- 见名知意(比如
user_age
表示用户年龄,file_path
表示文件路径)。 - 常用风格:单词全小写 + 下划线(
user_name
),或全大写(环境变量专用,USER_NAME
)。
- 见名知意(比如
- 赋值与引用技巧:
- 赋值时:简单值可不用引号,带变量 / 空格用双引号,纯字符串用单引号。
- 引用时:用
$变量名
,若变量后紧跟其他字符,用${变量名}
(比如${name}123
,避免被解析成$name123
)。
- 特殊场景:
- 取消变量用
unset 变量名
(不加 $)。 - 导出环境变量用
export
或declare -x
。 - 脚本中尽量用双引号包裹变量,避免空格导致的解析错误。
- 取消变量用
多参考系统自带脚本(比如/etc/init.d/functions
)的变量定义方式,慢慢会形成自己的规范~
如涉及版权问题,请联系作者处理!!!