Linux Shell编程及自动化运维实现-1-变量

Shell 脚本编程中,变量是最基础也是最重要的概念。一个固定的字符串去表示不固定的内容,让脚本变得灵活、可复用。

本文将系统讲解 Shell 变量的定义、引用、运算、环境变量、位置变量,并通过实战案例带你掌握变量的正确使用方法。


简介

什么是 Shell

Shell 是命令解释器,一种应用程序。它是用户使用 Linux 的桥梁,用户的大部分工作都是通过 Shell 完成的。

Shell 语言的特点:

  • Shell 语言是指 UNIX 操作系统的命令语言,同时也是该命令语言的解释程序的简称
  • Shell 本身是一个用 C 语言编写的程序
  • Shell 既是一种命令语言,又是一种程序设计语言
  • 作为命令语言,它交互式地解释和执行用户输入的命令
  • 作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支
  • 它虽然不是 Linux 系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行
  • 对于用户来说,shell 是最重要的实用程序

Shell 能做什么

场景示例
自动化系统初始化update、软件安装、时区设置、安全策略
自动化软件部署LAMP、LNMP、Tomcat、LVS、Nginx
应用管理KVM、集群管理扩容、MySQL、DELL R720 批量 RAID
日志分析处理PV、UV、200 代码、top 100、grep/awk
自动化备份恢复MySQL 完全备份/增量 + Crond
自动化管理批量远程修改密码、软件升级、配置更新
信息采集及监控收集系统/应用状态信息,CPU、Mem、Disk、Net、TCP Status
配合 Zabbix 采集收集系统/应用状态信息,CPU、Mem、Disk、Net
自动化扩容增加云主机 → 业务上线
趣味编程俄罗斯方块、打印三角形、打印圣诞树、排序算法

Shell 执行方式

准备测试脚本:

[root@localhost]# vim file1

echo "hello 1234"
read -p "请输入您的姓名:" name
echo "哈哈 $name 是大笨蛋"

四种执行方式:

执行方式命令运行环境
方式 1bash file1子 Shell
方式 2sh file1子 Shell(which bashwhich sh 发现是同一个文件)
方式 3. file1当前 Shell
方式 4source file1当前 Shell(同方式 3)

子 Shell vs 当前 Shell 的区别:

# 准备环境
[root@localhost ~]# vim bash.sh
#!/usr/bin/bash
cd /home/
ls

# 分别使用当前Shell和子 Shell 执行(. bash.sh 或 source bash.sh)
[root@localhost ~]# bash bash.sh 
[root@localhost ~]# 
[root@localhost ~]# . bash.sh 
[root@localhost home]# 
# 观察:当前shell让目录改变了

关键区别bashsh 是在子 Shell 中执行,不影响当前环境;.source 是在当前 Shell 中执行,用于影响当前 Shell 环境(如修改目录、设置变量等)。

Shell 解释器位置

# 查看系统支持的 Shell
[root@localhost home]# cat /etc/shells

# 或使用
[root@localhost ~]# chsh -l

自定义变量

什么是 Shell 变量

Shell 变量:用一个固定的字符串去表示不固定的内容,便于修改。

变量基本操作

操作语法示例
定义变量变量名=变量值name="zhangsan 666"
引用变量$变量名${变量名}echo $name
查看变量echo $变量名echo $name
查看所有变量setset(包括自定义变量和环境变量)
取消变量unset 变量名unset name

正确定义变量

[root@localhost ~]# name="zhangsan 666"
[root@localhost ~]# echo $name
zhangsan 666

错误定义示范

# 错误 1:变量名不能以数字开头
[root@localhost ~]# 2name="lisi 666"
-bash: 2name=lisi 666: command not found

# 错误 2:等号左右两侧不能有空格
[root@localhost ~]# name = "lisi 666"
-bash: name: command not found

# 错误 3:变量的值如果有空格,必须用引号包含
[root@localhost ~]# name=lisi 666
-bash: 666: command not found

变量命名规则

  • 命名只能使用英文字母、数字和下划线
  • 首个字符不能以数字开头
  • 中间不能有空格,可以使用下划线(_
  • 不能使用标点符号
  • 不能使用 bash 里的关键字(可用 help 命令查看保留关键字)
  • 建议变量名使用五个字母以上

重复定义变量(变量叠加)

# 定义变量 aa 的值是 123
[root@localhost ~]# aa=123

# 重复定义:原 aa 的值加上 456
[root@localhost ~]# aa="$aa"456

# 调用变量 aa,发现值已经变成了 123456
[root@localhost ~]# echo $aa
123456

# 在进行变量叠加时,也可以使用 ${变量名} 格式
[root@localhost ~]# aa=${aa}789
[root@localhost ~]# echo $aa
123456789

注意:在进行变量叠加时,变量名需要用双引号或 ${} 包含。

变量调用示例

准备一台虚拟机:IP为192.168.100.10

使用变量前:

[root@localhost ~]# vim ping.sh

# 需求:编写测试主机在线的脚本
# 当主机在线提示在线,当主机不在线提示不在线

ping -c1 192.168.100.10 &>/dev/null && echo 192.168.100.10 up || echo 192.168.100.10 down

输出示例

# 192.168.100.10未开机
[root@localhost ~]# bash ping.sh 
192.168.100.10 down

# 192.168.10.10开机
[root@localhost ~]# bash ping.sh 
192.168.100.10 up

问题:如果更换测试 IP,需要修改脚本中的三个部分(ping 目标、echo up、echo down)。

使用变量后:

[root@localhost ~]# vim ping.sh

#!/bin/bash
ip=192.168.100.10
ping -c1 $ip &>/dev/null && echo $ip up || echo "$ip down"
# 授权脚本(加执行权限)
[root@localhost ~]# chmod +x ping.sh

# 执行脚本
[root@localhost ~]# ./ping.sh

优势:添加变量后,更换 IP 只需修改一处即可。

三目表达式说明:

符号含义
&&前面的命令成功(返回 0),执行后面的命令
`

交互定义变量(read)

read 命令:从键盘读入变量值。

语法:

read 变量名
read -p "提示信息" 变量名

示例:

[root@localhost ~]# read -p "请输入您测试的IP地址:" ip
请输入您测试的IP地址:192.168.100.100
[root@localhost ~]# echo $ip
192.168.100.100

三种引号的区别

引号类型说明
" "弱引用转义大部分符号,但 $`\ 仍保持特殊含义
' '强引用转义一切符号
` `命令替换优先执行内部的命令

双引号示例 1:

# 错误示范:shell 把空格识别为命令分隔符
[root@localhost ~]# schoo=1000 phone
-bash: phone: command not found

# 正确示范:变量值中的空格被转义为一个普通符号
[root@localhost ~]# schoo="1000 phone"
[root@localhost ~]# echo $schoo
1000 phone

双引号示例 2:

# 错误示范:已有变量的基础上再追加内容
[root@localhost ~]# schoo=$schoo is good
-bash: is: command not found
# 没有加引号,被识别为两条命令

# 正确示范:加了双引号,组成整体,空格失去含义
[root@localhost ~]# schoo="$schoo is good"
[root@localhost ~]# echo $schoo
1000 phone is good

单引号示例:

[root@localhost ~]# schoo='$schoo 666'
# 单引号,转义一切符号

[root@localhost ~]# echo $schoo
$schoo 666
# $ 也被转义了,一切都被转义了

反引号示例:

[root@localhost ~]# schoo=`date`
# 反引号是优先执行:先执行 date 的命令,再执行定义变量

[root@localhost ~]# echo $schoo
Thu Jun 4 18:09:28 CST 2026
# 所以看到变量的结果,是时间

反引号 `command` 等价于 $(command),推荐使用 $() 语法,更易读。


整数运算

方法一:expr

# 语法
expr 1 + 2
expr $num1 + $num2

# 运算符:+(加)、-(减)、\*(乘,* 是任意字符,使用 \ 转义)、/(除)、%(取余)

示例:

[root@localhost ~]# num1=9
[root@localhost ~]# num2=10
[root@localhost ~]# expr $num1 + $num2
19

案例:计算学员成绩总分

[root@localhost ~]# vim sum.sh

#!/bin/bash
read -p "请输入您的第一门成绩: " number1
read -p "请输入您的第二门成绩: " number2
echo -n "总成绩是: "
expr $number1 + $number2
[root@localhost ~]# chmod +x sum.sh
[root@localhost ~]# bash sum.sh 
请输入您的第一门成绩: 12
请输入您的第二门成绩: 99
总成绩是: 111

方法二:$(())

# 语法
echo $(($num1 + $num2))
echo $((num1 + num2))      # 可以省略 $
echo $((5 - 3 * 2))        # 结果为 -1
echo $((2 ** 3))           # 幂运算:2 的 3 次方,结果为 8

方法三:$[]

# 语法
echo $[5 + 2]    # + - * / %
echo $[5 ** 2]   # 幂运算:25

方法四:let

# 示例
let sum=2+3; echo $sum    # 输出 5
let i++; echo $i          # 自增

四种运算方式对比:

方法语法支持幂运算说明
exprexpr 1 + 2不支持需要空格分隔,乘号需转义
$(())echo $((1+2))支持 **推荐,语法简洁
$[]echo $[1+2]支持 **较老的语法
letlet sum=1+2支持 **适合变量赋值

小数运算(了解)

需要安装计算器程序 bc

# 安装 bc
yum -y install bc

# 基本运算    
echo "2 * 4" | bc         # 输出 8
echo "2 ^ 4" | bc         # 输出 16(幂运算)
echo "scale=2; 6 / 4" | bc  # 输出 1.50(保留两位小数)
参数说明
bc交互式运算器
scale=2保留小数点后两位

环境变量(了解)

前言

自定义变量只能在当前 Shell 中生效,其他 Shell 是不生效的。说白了,你的变量只能你用。那如果有些变量,需要所有的用户都使用,怎么办呢?

定义环境变量

方法语法说明
直接声明export back_dir2=/home/backup直接声明环境变量
转换声明export back_dir1将已有的自定义变量转换成环境变量

变量作用范围:在当前 Shell 和子 Shell 有效。

持久化环境变量

文件作用范围说明
~/.bash_profile当前用户当前用户登录后一直生效
/etc/profile所有用户所有用户登录后一直生效

示例

# 定义普通变量 1
[root@localhost ~]# abc=123

# 定义普通变量 2
[root@localhost ~]# def=456

# 打开子 Shell
[root@localhost ~]# bash

# 调用普通变量,失败
[root@localhost ~]# echo $abc
(空)

[root@localhost ~]# echo $def
(空)

# 退出子 Shell
[root@localhost ~]# exit

# 将变量声明为环境变量(儿子 Shell 都能用)
[root@localhost ~]# export abc

# 打开子 Shell
[root@localhost ~]# bash

# 发现变量可以用了
[root@localhost ~]# echo $abc
123

# 普通变量还是不行
[root@localhost ~]# echo $def
(空)

位置变量和预定义变量(了解)

位置变量

位置变量用于在脚本中接收用户传入的参数。

语法:

命令  参数1 参数2 参数3 ...
$0    $1    $2    $3    ...
变量说明
$0脚本名/程序名
$1 ~ $9第 1 到第 9 个参数
$10 以后需要用 ${10} 格式

示例:计算两门学科的平均分

[root@localhost ~]# vim avg.sh

#!/bin/bash
echo "($1+$2)/2" | bc
[root@localhost ~]# chmod +x avg.sh

# 测试脚本
[root@localhost ~]# ./avg.sh 88 77
82

预定义变量

变量说明
$0脚本名/程序名
$*所有的参数
$#参数的个数
$?上一个命令的返回值(0 是成功,非零失败)
$$程序的 PID

示例:

[root@localhost ~]# vim avg.sh

#!/bin/bash
echo "($1+$2)/2" | bc
echo "该程序名为 $0"
echo "该程序使用了 $# 个参数"
echo "该程序的参数如下:$*"
[root@localhost ~]# ./avg.sh 60 50
55
该程序名为 ./avg.sh
该程序使用了 2 个参数
该程序的参数如下:60 50

总结

  1. 位置变量就是 $1$2$3$4
  2. 位置变量预先已经被定义好了
  3. 用户使用时,必须携带参数
  4. 位置变量不是程序设计的唯一方法,read 也可以

位置变量 vs read

两种方法都可以实现参数输入:

#!/bin/bash
read -p "请输入您的第1门成绩: " num1
read -p "请输入您的第2门成绩: " num2
echo -n "您的平均成绩是:"
echo "($num1+$num2)/2" | bc
方式特点适用场景
位置变量参数直接跟在命令后面适合命令行快捷调用
read交互式输入,有提示信息适合需要引导用户输入的场景

实战案例

案例 1:自动创建用户并设置初始密码为123456

#!/bin/bash

read -p "please input username: " name
useradd $name
echo "123456" | passwd --stdin $name &>/dev/null
echo "$name create finished, the password is 123456"

执行效果:

[root@localhost ~]# bash create_user.sh 
please input username: abcdefg
abcdefg create finished, the password is 123456

案例 2:配置本地 YUM 源

#!/bin/bash

# 挂载光盘
mount /dev/cdrom /mnt &>/dev/null

# 删除原有仓库配置
rm -rf /etc/yum.repos.d/*

# 创建新的 YUM 仓库配置
cat << EOF > /etc/yum.repos.d/yum.repo

[local]

name=localyum baseurl=file:///mnt enabled=1 gpgcheck=0 EOF # 检查仓库列表 yum repolist all


常见问题

变量定义时报错 “command not found”

检查等号两侧是否有多余的空格。在 Shell 中,= 两侧不能有空格。

变量值中有空格怎么处理

使用双引号包裹变量值:name="hello world"

变量在子 Shell 中无法使用

使用 export 将变量声明为环境变量:export 变量名

如何让变量永久生效

  • 当前用户永久生效:将变量写入 ~/.bash_profile
  • 所有用户永久生效:将变量写入 /etc/profile

最佳实践

  1. 变量名命名规范

    • 使用下划线分隔单词:db_password 而非 dbpassword
    • 变量名至少五个字母以上
    • 避免使用关键字和保留字
  2. 引号使用原则

    • 字符串赋值时使用双引号:name="hello world"
    • 需要完全转义时使用单引号:path='$HOME/test'
    • 命令执行使用 $()date=$(date)
  3. 变量叠加使用 ${}


    path="${path}:/usr/local/bin"

  4. 整数运算优先使用 $(())


    echo $(($a + $b))

  5. 使用 $? 检查命令是否成功


    [root@localhost ~]# ls /home/
    abcdefg
    [root@localhost ~]# echo $?
    0
    [root@localhost ~]# ls /home/aaa
    ls: cannot access /home/aaa: No such file or directory
    [root@localhost ~]# echo $?
    2


总结

通过本章节的学习,你应该掌握了:

  • 理解 Shell 的概念、特点和作用
  • 掌握 Shell 的四种执行方式(bash、sh、.、source)及区别
  • 掌握自定义变量的定义、引用、查看、删除操作
  • 理解变量命名规则和错误定义示范
  • 掌握变量叠加的正确方法
  • 理解三种引号的区别(双引号、单引号、反引号)
  • 掌握四种整数运算方法(expr、$(())、$[]、let)
  • 了解小数运算(bc)
  • 理解环境变量和自定义变量的区别
  • 掌握环境变量的定义方法和持久化方式
  • 掌握位置变量($0 ~ $9)和预定义变量($*、$#、$?、$$)
  • 能够编写自动创建用户和配置 YUM 源的脚本

学习建议:Shell 变量是 Shell 编程的基础。建议在虚拟机上动手练习每一个示例,特别是三种引号的区别和四种运算方式。变量叠加和位置变量是编写实用脚本的关键,务必熟练掌握。


🙋 学习路上不孤单,有坑一起填!



卡在参数调试、命令打架、功能没反应、资源失效?其他问题?直接戳我,也可以进群和同好交流!



📱 个人QQ:3838586495    👥 交流Q群:1094091455    📮 邮箱:leyan2504@163.com



内容帮你省了大把踩坑时间?可以文末小小打赏鼓励一波,也欢迎安利给身边学习的朋友~



✨ 欢迎来评论区「交作业」:分享你的配置思路、提出疑难问题;评论区正确填写邮箱,不错过任何人的解答回复!


暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇