一、Shell 脚本概念
脚本就是把多条 Linux 命令按执行顺序写入后缀为.sh的文件,给文件赋予执行权限,搭配if/while/for等控制语句,实现复杂自动化操作。 通俗理解:把手动一条条敲的命令写到文件,一键自动执行。
二、常见使用场景
- 批量部署:批量装软件、配置多台服务器、发布项目
- 服务器监控:监控 CPU、内存、磁盘、端口,异常输出告警
- 定时数据备份:定时备份日志、数据库、业务文件
- 自动化运维:清理日志、批量启停服务、同步文件、统一权限
三、脚本标准构成
1. 解析器声明(首行必须写)
#!/bin/bash / #!/bin/sh 作用:告诉操作系统用哪个解释器解析本脚本,不加会默认使用当前终端 shell。
2. 注释
# 单行注释,执行脚本时忽略,用来写功能、参数、注意事项。
3. 执行指令
脚本核心代码:Linux 命令、变量、判断、循环、运算等。
完整基础示例 test.sh
bash
运行
#!/bin/bash
# 脚本名称:test.sh
# 功能:基础演示脚本
# 作者:运维
echo "我的第一个shell脚本"
ls /root
四、脚本 4 种执行方式 + 语法检测
1. 添加执行权限
bash
运行
chmod +x test.sh # 赋予文件执行权限
2. 四种执行方式
方式 1:sh/bash 直接调用(新开子 shell 运行,变量不影响当前终端)
bash
运行
sh test.sh
bash test.sh
方式 2:相对 / 绝对路径执行(./ 代表当前目录,子 shell 运行)
bash
运行
# 相对路径
./test.sh
# 绝对路径
/root/test.sh
方式 3:. 脚本名(当前 shell 执行,变量会留在终端)
bash
运行
. test.sh
方式 4:source 脚本名(和。完全等价,当前 shell 执行)
bash
运行
source test.sh
关键区分
- sh/bash/./ 执行:开启子 shell,脚本内变量执行完自动销毁,不污染当前终端
- source /. 执行:当前终端 shell运行,脚本变量执行后仍保留在环境中
3. 语法错误检测(不运行脚本,只检查语法)
bash
运行
sh -n test.sh
# 无输出代表语法无错误,报错则提示哪一行有问题
五、管道符 |
将前一条命令的输出,交给后一条命令作为输入。 案例:过滤系统中 nginx 进程
bash
运行
ps -ef | grep nginx
# ps -ef 输出所有进程,管道把结果传给grep过滤nginx相关内容
六、脚本输入输出
1. 输出:echo 打印内容到屏幕
bash
运行
echo "hello shell"
name="张三"
echo "名字是:$name"
2. 输入:read 接收用户手动输入,存入变量
案例:交互式输入姓名
bash
运行
#!/bin/bash
echo "请输入你的姓名:"
read username # 等待用户输入,内容存入username变量
echo "你输入的名字是:$username"
简化写法(一行提示 + 接收)
bash
运行
read -p "请输入年龄:" age
echo $age
七、重定向
1. 输出重定向
>覆盖输出:清空文件原有内容,写入新内容>>追加输出:在文件末尾新增内容,不覆盖 文件描述符:1标准正确输出(默认省略)2标准错误输出&代表所有输出(正确 + 错误)
案例演示:
bash
运行
# 正确输出覆盖写入log.txt
ls / > log.txt
# 错误输出单独存入err.log
ls /不存在目录 2> err.log
# 正确、错误全部写入all.log
ls /不存在目录 &> all.log
# 追加写入日志
echo "新增日志" >> log.txt
2. 输入重定向
把文件内容作为命令输入
bash
运行
# 将test.txt内容交给cat读取
cat < test.txt
3. 多行分界符重定向(here-doc)
分界符自定义(EOF/fof 任意字符)
- 仅打印到屏幕
bash
运行
cat << fof
这是第一行
这是第二行 $USER
fof
- 覆盖写入文件
bash
运行
cat > info.txt << fof
姓名:张三
用户:$USER
fof
- 追加写入文件
bash
运行
cat >> info.txt << fof
追加一行内容
fof
分界符引号区别
- 分界符不加引号:识别
$变量,会解析变量值 - 分界符加单引号
'fof':所见即所得,不解析变量,原样输出符号 示例:
bash
运行
# 不识别变量,直接打印$USER字符串
cat << 'fof'
当前用户:$USER
fof
八、变量
定义规则
格式:变量名=值,等号左右不能有空格 错误:name = 李四 正确:name="李四"
变量四大分类
1. 自定义变量(用户自己定义)
bash
运行
name="运维"
echo $name
2. 系统内置变量(操作系统自带)
bash
运行
echo $USER # 当前登录用户
echo $PATH # 系统环境路径
echo $HOSTNAME # 主机名
3. 全局 / 局部变量
- 全局:脚本内全部代码可用
- 局部:函数内用
local定义,仅函数内部生效
bash
运行
test(){
local num=10 # 局部变量,函数外无法调用
echo $num
}
test
4. 位置变量(执行脚本时传参)
执行脚本格式:./test.sh 参数1 参数2 参数3
$1第一个参数,$2第二个,依次类推 案例 test.sh
bash
运行
#!/bin/bash
echo "第一个参数:$1"
echo "第二个参数:$2"
执行:./test.sh 苹果 香蕉 输出: 第一个参数:苹果 第二个参数:香蕉
5. 预定义特殊变量(固定含义)
表格
| 变量 | 作用 |
|---|---|
| $0 | 当前脚本完整名称 / 路径 |
| $# | 传入参数总个数 |
| $* | 所有参数,整体视为一串字符串 |
| $@ | 所有参数,独立分开,循环推荐使用 |
| $$ | 当前脚本运行的进程 PID 号 |
案例:
bash
运行
#!/bin/bash
echo "脚本名:$0"
echo "参数总数:$#"
echo "所有参数:$*"
echo "进程号:$$"
执行:./test.sh a b c
引号区别(取值时)
- 单引号 '' 强引用:所见即所得,不解析变量、特殊符号
bash
运行
name="小明"
echo '$name' # 输出 $name
- 双引号 "" 弱引用:识别
$变量,保留空格
bash
运行
echo "$name" # 输出 小明
- 不加引号:识别变量,空格会分割内容,不推荐带空格字符串使用
九、Shell 算术计算(整合两张截图实操案例 + 报错解析)
基础说明
- Shell 原生仅支持整数运算 ,小数浮点运算必须使用
bc工具 - 算术运算符:
+加、-减、*乘、/整除、%取模(取余数) - 截图统一预设变量:
bash
运行
a=40
b=3
方式 1:expr 计算(截图实操 + 报错重点)
核心规则
- 运算符左右必须加空格,无空格不会计算,直接原样输出字符串
- 乘号
*是 shell 通配符,直接使用会报语法错误,必须加反斜杠转义\*
bash
运行
# 1.加法(空格正确,正常计算)
expr $a + $b
# 输出:43
# 2.无空格,不会运算,直接输出字符串
expr $a+$b
# 输出:40+3
# 3.减法
expr $a - $b
# 输出:37
# 4.直接写* 报错(截图报错:expr: 语法错误:未预期的参数 "1.log")
expr $a * $b
# 5.乘号转义 \* 正确写法
expr $a \* $b
# 输出:120
# 6.除法(整除,舍弃小数)
expr $a / $b
# 输出:13
# 7.取模(求余数)
expr $a % $b
# a=40时输出1;修改a=41后执行,输出2
expr $a % $b
方式 2:let 计算(直接赋值给变量)
bash
运行
# 定义变量接收计算结果
let sum=$a+$b
# 打印结果
echo $sum
# a=41,b=3时输出 44
方式 3:$(()) 双括号运算(最推荐,简洁无转义)
两种用法:直接输出 / 赋值给变量
bash
运行
# 用法1:直接echo打印运算结果
echo $(($a+$b))
# 输出:44
# 用法2:把计算结果存入自定义变量ccc
ccc=$(($a+$b))
# 打印变量
echo $ccc
# 输出:44
方式 4:bc 浮点小数运算(补充,截图未演示)
bash
运行
a=10
b=3
# -l 参数加载数学库,保留小数
echo "$a / $b" | bc -l
# 输出 3.3333333333
四种计算方式对比总结
表格
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| expr | 兼容所有 shell | 运算符必须空格、乘法要转义 | 老旧脚本、简单运算 |
| let | 可直接赋值变量 | 只能整数,语法兼容性一般 | 脚本内变量运算 |
| $(( )) | 语法最简、无需转义、支持复杂四则 | 仅整数 | 日常脚本首选 |
| bc | 支持小数、高精度计算 | 写法繁琐 | 浮点、财务计算 |