在Linux / Unix Shell中,变量是存储数据的容器。用于临死保存字符串、数字、路径等信息
变量命名规则
-
只能包含字母、数字、下划线
-
不能以数字开头
-
区分大小写(
name和NAME是不同的) -
建议使用大写(环境变量)或小写(局部变量)
变量的设置方式:
bash
# 语法:变量名=值(等号两边不能有空格)
name="John"
age=25
path="/home/user"
# 正确写法
name="John"
# 错误写法(等号两边不能有空格)
name = "John" # ❌
name= "John" # ❌
name =John # ❌
1.字符串变量
字符串变量:可以不使用引号包裹,只有当字符串中不包含任何特殊字符时才能省略引号
安全的情况:
bash
# 1. 只有字母
name=John
city=Beijing
# 2. 字母和数字
user_id=user123
version=v2_0
# 3. 字母、数字、下划线、连字符(不能有空格)
file_name=my-file_v1
# 4. 简单路径(无空格)
path=/home/user/documents
# ✅ 这些都可以正常工作
name=John
echo $name # 输出: John
greeting=Hello
echo $greeting # 输出: Hello
绝对不能省略引号的情况:
bash
# 1. 包含空格(最常见)
name=John Smith # ❌ 错误!Shell 会认为 Smith 是另一个命令
# 报错: Smith: command not found
# 正确写法
name="John Smith"
# 2. 包含特殊字符
message=Hello&World # ❌ & 会被解释为后台运行
path=/home/user/*.txt # ❌ * 会被展开
text=重定向>文件 # ❌ > 会被解释为重定向
# 正确写法
message="Hello&World"
path="/home/user/*.txt"
text="重定向>文件"
黄金法则:除非100%确定可以不使用引号,否则都建议加上引号,这是保险起见,避免发生错误的策略
字符串变量中双引号和单引号的区别:
核心区别:双引号会解释特殊字符,单引号会原样输出
| 特性 | 双引号 " " |
单引号 ' ' |
|---|---|---|
变量替换 ($var) |
✅ 会替换 | ❌ 不替换,原样输出 |
命令替换 (cmd 或 $(cmd)) |
✅ 会执行 | ❌ 不执行,原样输出 |
转义字符 (\n, \t, \$ 等) |
✅ 部分生效(需 -e) |
❌ 全部原样 |
通配符展开 (*, ?) |
❌ 不展开(当作普通字符) | ❌ 不展开 |
历史扩展 (!) |
⚠️ 可能被解释(需注意) | ❌ 不解释 |
| 内部引号 | 可包含单引号 | 可包含双引号 |
什么是变量替换:
是指Shell将变量名替换成它所代表的实际值的过程。简单地说就是:把$变量名变成变量里存的内容
bash
[root@master ~]# name="Alice"
[root@master ~]# echo $name # 变量替换,$name被替换成"Alice"
Alice
[root@master ~]# echo '$name' # 不会发生变量替换,直接输出字符串
$name
[root@master ~]# name1='Jack'
[root@master ~]# echo $name1 # name1的变量用单引号包裹起来,但是为什么还是会输出变量的内容
Jack
bash
[root@master ~]# echo "$name1"
Jack
[root@master ~]# echo '$name1' # 单引号的作用是:让Shell把里面的内容当成普通文本
$name1
更直接的例子:
bash
[root@master ~]# name2='$name' # 单引号:表示$是一个普通的字符,不是Linux中的$指令(原样输出)
[root@master ~]# name3="$name" # 双引号:会解释变量中的命令、指令
[root@master ~]# echo name2 # 会输出name2这个文本,因为没有用$字符来引用变量的值
name2
[root@master ~]# echo $name2 # 发生变量替换,$name2被替换成name2的值,即被替换为'$name',单引号不会解释字符串中的字符,直接原样输出
$name
[root@master ~]# echo $name3 # 发生变量替换,双引号会解释字符串中的特殊字符
Alice
2.数字变量
在Linux中。数字变量的赋值和使用有一些特殊规则
1.基本数字赋值
直接赋值
bash
[root@master ~]# num1=10 # 直接赋值数字(实际上作为字符串存储)
[root@master ~]# num2=20
[root@master ~]# num3=100
[root@master ~]# echo $num1
10
[root@master ~]# echo $num2
20
[root@master ~]# echo $num3
100
使用let命令
bash
[root@master ~]# let num=10 # let命令用于变量计算
[root@master ~]# echo $num
10
[root@master ~]# let "num = 200" # 带引号也可以
[root@master ~]# echo $num
200
[root@master ~]# let a=1 b=2 c=3 # 多个变量赋值
[root@master ~]# echo $a
1
[root@master ~]# echo $b
2
使用双括号
bash
[root@master ~]# ((num=1000))
[root@master ~]# echo $num
1000
[root@master ~]# ((num = 520))
[root@master ~]# echo $num
520
[root@master ~]# ((a = 1,b=2, c=3)) # 多个赋值
[root@master ~]# echo $a $b $c
1 2 3
2.不同进制的数值赋值
1.十进制(默认)
bash
[root@master ~]# decimalism_num=123
[root@master ~]# echo $decimalism_num
123
2.八进制(以数字0开头)
bash
[root@master ~]# octal_num=016
[root@master ~]# echo $octal_num
016
[root@master ~]# octal_num=377
[root@master ~]# echo $octal_num
377
[root@master ~]# octal_num=0377
[root@master ~]# echo $octal_num
0377
[root@master ~]# echo $((octal_num)) # 算术运算,自动转换成十进制
255
[root@master ~]# octal_num=016
[root@master ~]# echo $((octal_num))
14
[root@master ~]# ((result = octal_num)) # 算术运算环境
[root@master ~]# echo $result
14
[root@master ~]# let num=octal_num # let命名也会发生进制转换
[root@master ~]# echo $num
14
注:Shell中的八进制/十六进制只在算术运算中发生,普通echo输出不会进行转换
bash
[root@master ~]# octal_num=0377
# 实际上存储的是字符串 "0377",不是数字
# 验证:查看变量内容
[root@master ~]# echo $octal_num
0377 # 输出原样,因为是字符串
# 验证数据类型(Shell 中一切都是字符串)
[root@master ~]# echo "${#octal_num}"
4 # 长度是4,证明是4个字符 '0','3','7','7'
为什么Shell会这样设计:
原因:
- Shell变量本质是字符串
- 只有明确要求数字计算时,才会将字符串解释为数字
3.十六进制(0X开头或0x开头)
bash
[root@master ~]# hex_num=0x12
[root@master ~]# echo $hex_num
0x12
[root@master ~]# echo $((hex_num))
18
3.算术运算赋值
1.使用let命令
bash
[root@master ~]# a=10
[root@master ~]# let b=a + 5
-bash: let: +: syntax error: operand expected (error token is "+")
[root@master ~]# let b=a+5
[root@master ~]# echo $b
15
[root@master ~]# let b=a*2
[root@master ~]# echo $b
20
[root@master ~]# let5/2
-bash: let5/2: No such file or directory
[root@master ~]# let 5/2
[root@master ~]# let x=5/2 # 除法,整数
[root@master ~]# echo $x
2
[root@master ~]# let x=5-1
[root@master ~]# echo $x
4
[root@master ~]# let x=5%2
[root@master ~]# echo $x
1
[root@master ~]# let x=2**3
[root@master ~]# echo $x
8
bash
[root@master ~]# let a++
[root@master ~]# echo $a
2
2.使用双括号
bash
[root@master ~]# a=10
[root@master ~]# ((a = a + 5))
[root@master ~]# echo $a
15
[root@master ~]# ((a += 5)) # 简写
[root@master ~]# echo $a
20
[root@master ~]# echo ((a++)) # 自加1
-bash: syntax error near unexpected token `('
[root@master ~]# echo $((a++)) # 自加1
20
[root@master ~]# echo $a
21
[root@master ~]# echo $((++a)) # 先加后用,和C一样,和Java一样
22
[root@master ~]# echo $a
22
[root@master ~]# ((a--)) # 自减
[root@master ~]# echo $a
21
[root@master ~]# ((sum = 10 + 20 + 30)) # 多个运算
[root@master ~]# echo $sum
60
4.数字变量的比较和判断
1.使用test或[ ]
\]在Linux中有两个作用: * 作为Shell中用于条件判断的命令,等价于test命令 * 作为通配符(字符集合),在路径扩展中用于配置指定范围内的任意一个字符 \[ \]用于条件判断的语法: ```bash # 语法:[ 条件表达式 ] (注意:括号和条件之间必须有空格) [ condition ] # 使用示例 if [ condition ]; then # 条件成立时执行 fi ``` 字符串比较:=还是!= ```bash [root@master ~]# str1="Hello" [root@master ~]# str2="World" [root@master ~]# [$str1 = $str2] -bash: [Hello: command not found [root@master ~]# [ $str1 = $str2] -bash: [: missing `]' [root@master ~]# [ $str1 = $str2 ] [root@master ~]# echo $? # 查看退出状态 1 # 1表示假,不相等 ``` 想一下前两次比较为什么会失败! # 你输入的命令(没有空格) \[$str1 = $str2
Shell 进行变量替换后
Hello = World
Shell 认为这是一个命令,命令名是 "[Hello"
因为找不到 "[Hello" 这个命令,所以报错
-bash: [Hello: command not found
正确的写法是:[ 和 ]两边都需要有空格!
bash
[root@master ~]# var1="apple"
[root@master ~]# var2="apple"
[root@master ~]# [ var1 == var2 ]
[root@master ~]# echo $?
1
[root@master ~]# [ $var1 = $var2 ]
[root@master ~]# echo $?
0
[root@master ~]# [ $str1 != $str2 ]
[root@master ~]# echo $?
0
更好的写法:给变量加引号
bash
[root@master ~]# [ "$str1" = "$str2" ]
[root@master ~]# echo $?
1
数字比较:
bash
# 数字比较(注意:不能用 > <,要用选项)
[ $a -eq $b ] # 等于 (equal)
[ $a -ne $b ] # 不等于 (not equal)
[ $a -gt $b ] # 大于 (greater than)
[ $a -lt $b ] # 小于 (less than)
[ $a -ge $b ] # 大于等于 (greater or equal)
[ $a -le $b ] # 小于等于 (less or equal)
bash
[root@master ~]# a=10
[root@master ~]# b=20
[root@master ~]# [ $a -eq $b ] # -eq表示euqal
[root@master ~]# echo $?
1
[root@master ~]# echo $[ $a -ne $b ]
-bash: 10 -ne 20 : syntax error in expression (error token is "20 ")
[root@master ~]# [ $a -ne $b ] # -ne 表示not equal
[root@master ~]# echo $?
0
[ ] 和 $(( )) 是算术运算 结构,只支持算术运算符(+、-、*、/、%、<、>、==、!= 等),不支持 -ne、-eq、-gt 这些 test 命令的比较选项。
bash
[root@master ~]# if [ $a -ne $b ]; then
> echo "不相等"
> fi
不相等
使用双括号进行数字变量的判断(推荐)
bash
a=10
b=20
# (( )) 用于条件判断
(( a != b ))
echo $? # 输出: 0 (真)
# 获取比较结果(0或1)
result=$((a != b))
echo $result # 输出: 1 (真值在算术环境中是1)
# 注意:在 (( )) 中,真为1,假为0
echo $((10 != 20)) # 输出: 1
echo $((10 == 20)) # 输出: 0
# 用于 if 判断
if (( a != b )); then
echo "不相等"
fi
bash
a=10
b=20
# 比较运算符(返回 1=真,0=假)
echo $((a == b)) # 等于
echo $((a != b)) # 不等于
echo $((a > b)) # 大于
echo $((a < b)) # 小于
echo $((a >= b)) # 大于等于
echo $((a <= b)) # 小于等于
# 逻辑运算符
echo $((a == 10 && b == 20)) # 逻辑与(两个都为真才真)
echo $((a == 10 || b == 30)) # 逻辑或(一个为真就真)
echo $((!(a == 10))) # 逻辑非