跳转到内容

Shell变量和数据类型

课程介绍

Shell变量是Shell脚本编程的核心概念,理解变量的定义、引用、作用域以及数据类型对于编写高效的Shell脚本至关重要。本课程将深入讲解Shell变量的各种用法,包括普通变量、环境变量、只读变量、数组等,以及字符串操作和数字运算等高级特性。

1. 变量基础

1.1 变量命名规则

Shell变量命名需要遵循以下规则:

命名规则

  • 变量名只能包含字母(a-z,A-Z)、数字(0-9)和下划线(_)
  • 变量名不能以数字开头
  • 变量名区分大小写(nameName是不同的变量)
  • 不能使用Shell关键字(如ifthenfor等)

示例

bash
# 正确的变量名
name="张三"
age=25
user_name="李四"
_count=100

# 错误的变量名
2name="王五"      # 不能以数字开头
user-name="赵六"   # 不能包含连字符
if="条件"         # 不能使用关键字

1.2 变量定义和赋值

Shell变量定义和赋值非常简单,直接使用变量名=值的格式。

基本语法

bash
变量名=值

注意事项

  • 等号两边不能有空格
  • 值中包含空格时需要用引号包裹

示例

bash
#!/bin/bash
# 正确的变量定义
name="张三"
age=25
city="北京"

# 错误的变量定义(等号两边有空格)
# name = "张三"  # 错误!

# 值中包含空格需要引号
# greeting=Hello World  # 错误!
greeting="Hello World"  # 正确

1.3 变量引用

使用$变量名${变量名}引用变量。

示例

bash
#!/bin/bash
name="张三"
age=25

# 使用$变量名
echo $name
echo $age

# 使用${变量名}(推荐)
echo ${name}
echo ${age}

# 区分变量名和后续字符
filename="test"
echo ${filename}.txt  # 输出:test.txt
echo ${filename}_bak   # 输出:test_bak

2. 变量类型

2.1 普通变量

普通变量是Shell脚本中最常用的变量类型。

示例

bash
#!/bin/bash
# 定义普通变量
name="张三"
age=25
city="北京"

# 使用变量
echo "姓名:$name"
echo "年龄:$age"
echo "城市:$city"

2.2 环境变量

环境变量是系统级别的变量,可以被所有子进程继承。

查看环境变量

bash
# 查看所有环境变量
env

# 查看特定环境变量
echo $PATH
echo $HOME
echo $USER

定义环境变量

bash
#!/bin/bash
# 定义环境变量(使用export)
export MY_VAR="Hello"

# 在子Shell中也可以访问
bash -c 'echo $MY_VAR'  # 输出:Hello

常用环境变量

变量说明
PATH命令搜索路径
HOME用户主目录
USER当前用户名
SHELL当前Shell路径
PWD当前工作目录
LANG系统语言设置

2.3 只读变量

只读变量定义后不能被修改或删除。

定义只读变量

bash
#!/bin/bash
# 定义只读变量
readonly PI=3.14159
readonly MAX_SIZE=1024

# 使用只读变量
echo "PI = $PI"
echo "MAX_SIZE = $MAX_SIZE"

# 尝试修改只读变量(会报错)
# PI=3.14  # 错误:readonly variable

2.4 局部变量

局部变量只在函数内部有效,使用local关键字定义。

示例

bash
#!/bin/bash
# 定义函数
my_function() {
    local local_var="局部变量"
    echo "函数内部:$local_var"
}

# 调用函数
my_function

# 在函数外部访问局部变量(无法访问)
echo "函数外部:$local_var"  # 输出:(空)

3. 字符串操作

3.1 字符串定义

Shell字符串可以使用单引号、双引号或不使用引号定义。

示例

bash
#!/bin/bash
# 单引号字符串(不解析变量)
str1='Hello $name'
echo $str1  # 输出:Hello $name

# 双引号字符串(解析变量)
name="张三"
str2="Hello $name"
echo $str2  # 输出:Hello 张三

# 不使用引号(不能包含空格)
str3=Hello
echo $str3  # 输出:Hello

单引号vs双引号

特性单引号双引号
解析变量
解析转义字符
支持换行

3.2 字符串拼接

Shell支持多种字符串拼接方式。

示例

bash
#!/bin/bash
# 方法1:直接拼接
str1="Hello"
str2="World"
result1=$str1$str2
echo $result1  # 输出:HelloWorld

# 方法2:使用引号拼接
result2="$str1 $str2"
echo $result2  # 输出:Hello World

# 方法3:拼接变量和字符串
name="张三"
result3="你好,$name!"
echo $result3  # 输出:你好,张三!

3.3 字符串长度

使用${#变量名}获取字符串长度。

示例

bash
#!/bin/bash
str="Hello, World!"

# 获取字符串长度
echo "字符串长度:${#str}"  # 输出:13

# 获取变量长度
name="张三"
echo "姓名长度:${#name}"  # 输出:2

3.4 字符串截取

Shell支持多种字符串截取方式。

语法

bash
${变量名:起始位置:长度}

示例

bash
#!/bin/bash
str="Hello, World!"

# 从位置0开始截取5个字符
echo ${str:0:5}  # 输出:Hello

# 从位置7开始截取6个字符
echo ${str:7:6}  # 输出:World

# 从位置7开始截取到末尾
echo ${str:7}    # 输出:World!

# 截取最后3个字符
echo ${str: -3}  # 输出:ld!

3.5 字符串替换

Shell支持字符串替换操作。

语法

bash
${变量名/旧字符串/新字符串}      # 替换第一个匹配
${变量名//旧字符串/新字符串}     # 替换所有匹配

示例

bash
#!/bin/bash
str="Hello, World! Hello, Shell!"

# 替换第一个匹配
echo ${str/Hello/Hi}   # 输出:Hi, World! Hello, Shell!

# 替换所有匹配
echo ${str//Hello/Hi}  # 输出:Hi, World! Hi, Shell!

3.6 字符串删除

Shell支持从字符串开头或结尾删除子串。

语法

bash
${变量名#模式}      # 从开头删除最短匹配
${变量名##模式}     # 从开头删除最长匹配
${变量名%模式}      # 从结尾删除最短匹配
${变量名%%模式}     # 从结尾删除最长匹配

示例

bash
#!/bin/bash
filename="/home/user/test.txt"

# 从开头删除最短匹配
echo ${filename#*/}   # 输出:home/user/test.txt

# 从开头删除最长匹配
echo ${filename##*/}  # 输出:test.txt

# 从结尾删除最短匹配
echo ${filename%/*}   # 输出:/home/user

# 从结尾删除最长匹配
echo ${filename%%/*}  # 输出:(空)

4. 数字运算

4.1 基本运算

Shell支持基本的算术运算。

运算符

运算符说明
+加法
-减法
*乘法
/除法
%取模(求余)

方法1:使用$(( ))

bash
#!/bin/bash
num1=10
num2=5

# 基本运算
echo "加法:$((num1 + num2))"    # 输出:15
echo "减法:$((num1 - num2))"    # 输出:5
echo "乘法:$((num1 * num2))"    # 输出:50
echo "除法:$((num1 / num2))"    # 输出:2
echo "取模:$((num1 % num2))"    # 输出:0

方法2:使用let命令

bash
#!/bin/bash
num1=10
num2=5

# 使用let命令
let result=num1+num2
echo "加法:$result"  # 输出:15

let result=num1-num2
echo "减法:$result"  # 输出:5

方法3:使用expr命令

bash
#!/bin/bash
num1=10
num2=5

# 使用expr命令
result=$(expr $num1 + $num2)
echo "加法:$result"  # 输出:15

result=$(expr $num1 - $num2)
echo "减法:$result"  # 输出:5

4.2 自增自减

Shell支持自增和自减运算。

示例

bash
#!/bin/bash
num=10

# 自增
((num++))
echo "自增后:$num"  # 输出:11

# 自减
((num--))
echo "自减后:$num"  # 输出:10

# 前置自增
echo "前置自增:$((++num))"  # 输出:11

# 后置自增
echo "后置自增:$((num++))"  # 输出:11
echo "当前值:$num"          # 输出:12

4.3 浮点数运算

Shell本身不支持浮点数运算,需要使用bc命令。

示例

bash
#!/bin/bash
# 使用bc命令进行浮点数运算
result=$(echo "scale=2; 10 / 3" | bc)
echo "10 / 3 = $result"  # 输出:3.33

result=$(echo "scale=3; 3.14159 * 2" | bc)
echo "3.14159 * 2 = $result"  # 输出:6.283

5. 数组

5.1 数组定义

Shell支持一维数组,数组元素用空格分隔。

示例

bash
#!/bin/bash
# 定义数组
fruits=("苹果" "香蕉" "橙子" "葡萄")

# 访问数组元素
echo ${fruits[0]}  # 输出:苹果
echo ${fruits[1]}  # 输出:香蕉
echo ${fruits[2]}  # 输出:橙子
echo ${fruits[3]}  # 输出:葡萄

5.2 数组操作

获取数组长度

bash
#!/bin/bash
fruits=("苹果" "香蕉" "橙子" "葡萄")

# 获取数组长度
echo "数组长度:${#fruits[@]}"  # 输出:4

获取所有元素

bash
#!/bin/bash
fruits=("苹果" "香蕉" "橙子" "葡萄")

# 获取所有元素
echo ${fruits[@]}  # 输出:苹果 香蕉 橙子 葡萄

# 遍历数组
for fruit in ${fruits[@]}; do
    echo $fruit
done

添加元素

bash
#!/bin/bash
fruits=("苹果" "香蕉")

# 添加元素
fruits[2]="橙子"
fruits[3]="葡萄"

# 输出数组
echo ${fruits[@]}  # 输出:苹果 香蕉 橙子 葡萄

删除元素

bash
#!/bin/bash
fruits=("苹果" "香蕉" "橙子" "葡萄")

# 删除元素
unset fruits[1]

# 输出数组
echo ${fruits[@]}  # 输出:苹果 橙子 葡萄

6. 完整示例

示例1:学生成绩统计

bash
#!/bin/bash
# 学生成绩统计脚本

# 定义学生信息
name="张三"
age=18
class="高三(1)班"

# 定义成绩数组
scores=(85 92 78 90 88)

# 计算总分
total=0
for score in ${scores[@]}; do
    total=$((total + score))
done

# 计算平均分
average=$((total / ${#scores[@]}))

# 输出结果
echo "===== 学生成绩统计 ====="
echo "姓名:$name"
echo "年龄:$age"
echo "班级:$class"
echo "成绩:${scores[@]}"
echo "总分:$total"
echo "平均分:$average"
echo "======================"

示例2:字符串处理工具

bash
#!/bin/bash
# 字符串处理工具

# 输入字符串
read -p "请输入一个字符串:" str

# 输出字符串信息
echo "===== 字符串信息 ====="
echo "字符串:$str"
echo "长度:${#str}"
echo "前3个字符:${str:0:3}"
echo "后3个字符:${str: -3}"
echo "===================="

示例3:计算器脚本

bash
#!/bin/bash
# 简单计算器脚本

# 输入两个数字
read -p "请输入第一个数字:" num1
read -p "请输入第二个数字:" num2

# 计算结果
sum=$((num1 + num2))
difference=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))
remainder=$((num1 % num2))

# 输出结果
echo "===== 计算结果 ====="
echo "$num1 + $num2 = $sum"
echo "$num1 - $num2 = $difference"
echo "$num1 * $num2 = $product"
echo "$num1 / $num2 = $quotient"
echo "$num1 % $num2 = $remainder"
echo "=================="

课程总结

这节课我们学习了Shell变量和数据类型。

核心内容:

  • 变量命名规则和定义方法
  • 变量类型(普通变量、环境变量、只读变量、局部变量)
  • 字符串操作(定义、拼接、长度、截取、替换、删除)
  • 数字运算(基本运算、自增自减、浮点数运算)
  • 数组操作(定义、访问、遍历、添加、删除)

重要命令:

  • export:定义环境变量
  • readonly:定义只读变量
  • local:定义局部变量
  • unset:删除变量
  • bc:浮点数运算

变量和数据类型是Shell脚本编程的基础,掌握这些知识后,我们将在后续课程中学习条件判断、循环等高级特性。

课后练习

练习1(基础)

创建一个脚本,要求:

  1. 定义变量nameagecity
  2. 输出"姓名:xxx,年龄:xxx,城市:xxx"
  3. 计算并输出age + 10的结果

练习2(进阶)

创建一个字符串处理脚本,要求:

  1. 提示用户输入一个字符串
  2. 输出字符串的长度
  3. 输出字符串的前3个字符和后3个字符
  4. 将字符串中的所有"Hello"替换为"Hi"

练习3(拓展)

创建一个数组操作脚本,要求:

  1. 定义一个包含5个水果名称的数组
  2. 输出数组的长度
  3. 输出所有水果名称
  4. 添加一个新水果到数组
  5. 删除数组的第2个元素
  6. 输出最终的数组

评论区

专业的Linux技术学习平台,从入门到精通的完整学习路径