本文介绍了Shell脚本编程的基础知识,包括Shell语言特点、文件结构、变量定义与引用、脚本调用方式等核心内容。
重点讲解了条件判断(if语句)和循环结构(for/while循环)的语法与应用场景,并提供了多个实用示例,如磁盘容量监控、文件备份、日志巡检等。
文章还涉及Shell脚本参数传递和常见面试问题,适合初学者快速掌握Shell脚本编程基础。
通过具体案例展示了Shell在Linux环境下的自动化运维能力。
Shell 笔记
Shell 简介
Shell 是一门编程语言。
编程语言示例:
Java、Python、C++、C#、Php、Shell ....
特点:
基于 Linux 环境,可以原生运行的一个脚本语言
开发出来的脚本文件,一般是以
.sh结尾的可执行文件
| 文件后缀 | 文件类型 |
|---|---|
| xxx.sh | Shell 脚本 |
| xxx.py | Python 脚本 |
| xxx.jar | Jar 包 |
Shell 脚本文件结构
bash
#!/bin/bash # 或者 #!/bin/sh —— 头文件,用于定义编译器 # 逻辑体
1. 变量
a. 定义变量
基本格式:变量名=变量值(左右两边不允许出现空格)
bash
A=10 # 定义变量A的值是10 B="hello world"
使用Linux命令赋值:变量名=$(Linux命令)
bash
C=$(cat emp | wc -l)
b. 引用变量
格式:$变量名
bash
echo $A echo $B echo $C echo $A"$B" # 当变量需要跟其他内容拼接字符串时,需要双引号
2. 调用 Shell 脚本
a. 用 sh 调用
bash
sh task.sh sh /home/hadoop/2608/test/task.sh
b. 用 ./shell脚本 调用
前置条件:
必须在脚本的父目录
调用该脚本的用户必须要有执行权限
示例脚本
示例1:打印当前服务器磁盘剩余容量
bash
#!/bin/bash free=$(df -h | awk -F " " '{print $4}' | sed -n '6p') echo "当前磁盘剩余:"$free示例2:打印变量A + 20 的返回值
bash
#!/bin/bash D=$(($A + 20)) echo "变量A+20的结果是:"$D
练习1
开发 Shell 脚本,统计 Linux 的两块内存的总剩余容量。
3. 场景判断(if语句)
语法结构
bash
if 判断条件 then 要做的事情 elif 判断条件 then 要做的事情 else 要做的事情 fi
a. 判断条件注意事项
[ 比较值1 比较符号 比较值2 ]—— 空格不能少比较符:
| 比较符 | 含义 |
|---|---|
==或-eq | 等于 |
-gt | 大于(greater than) |
-lt | 小于(less than) |
-ge | 大于等于(greater equal) |
-le | 小于等于(less equal) |
-ne | 不等于(not equal) |
示例:统计文件个数
bash
# 开发shell脚本统计 /home/hadoop/2608 下面的文件个数 # 如果大于10个则打印"文件很多" # 如果大于5个则打印"文件正常" # 否则打印"文件过少" file_num=$(find /home/hadoop/2608 -type f | wc -l) if [ $file_num -gt 10 ] then echo "文件很多" elif [ $file_num -gt 5 ] then echo "文件正常" else echo "文件过少" fi
4. 循环
1. for循环
语法:
bash
for((i=1;i<=100;i++)) { 循环要做的事情 # $i }示例1:1~100求和
bash
sum=0 for((i=1;i<=100;i++)) { sum=$[$sum + $i] } echo $sum示例2:删除目录下所有文件
bash
total_num=$(find /home/hadoop/2608 -type f | wc -l) for((i=1;i<=$total_num;i++)) { file_name=$(find /home/hadoop/2608 -type f | grep -v "task" | head -$i | tail -1) rm -rf $file_name }示例3:打印1~100所有偶数
bash
for((i=1;i<=100;i++)) { x=$[$i % 2] if [ $x -eq 0 ] then echo $i fi }练习2
打印1~200以内的所有奇数求和
bash
tot=0 for((i=1;i<=200;i++)) { res=$[$i % 2] if [ $res == 1 ] then tot=$(($tot + $i)) fi } echo "奇数求和为:"$tot2. while循环(内容重定向)
语法:
bash
命令A | while read line; do 循环要做的事情 # $line 指向每一行内容 done
说明:
while read line的功能是逐行遍历命令A的标准输出,每一行的内容都会逐次赋值给变量$line
示例1:删除所有空文件
bash
find /home/hadoop/202608 -type f | while read line; do flag=$(du $line | awk -F " " '{print $1}') if [ $flag -eq 0 ] then rm -rf $line fi done示例2:查找文件内容包含"k"的文件
bash
find /home/hadoop -type f | while read line; do flag=$(grep "k" $line | wc -l) if [ $flag -gt 0 ] then echo $line fi done
示例3:在/tmp目录下找所有文件内容包含"a"的文件
思路:
先用
find -type f找到所有/tmp目录下的文件通过
while read line循环遍历通过
grep "a" $line判断是否存在内容"a"
练习3
将/home/hadoop/2222目录下所有的文件备份(如:xxx→xxx_bak)
bash
find /home/hadoop/2222 -type f | while read line; do cp $line $line"_bak" done
综合示例
示例1:生成100道随机小学加减法运算题
bash
# $RANDOM : 返回一个随机的整数 [0,3万多] # $RANDOM % 99 + 1 : 返回随机的 1~99 # read -t 10 -p "请输入你的年龄: " age read -t 10 -p "请确认,是否需要带出答案:(y/n)" flag for((i=1;i<=100;i++)) { num1=$[$RANDOM % 99 + 1] num2=$[$RANDOM % 99 + 1] if [ $num1 -le $num2 ] then tmp=$num2 num2=$num1 num1=$tmp fi x=$[$RANDOM % 2] if [ $x -eq 0 ] then if [ $flag == 'y' ] then echo $num1" + "$num2" = "$[$num1 + $num2] else echo $num1" + "$num2" = " fi else if [ $flag == 'y' ] then echo $num1" - "$num2" = "$[$num1 - $num2] else echo $num1" - "$num2" = " fi fi }示例2:监控磁盘剩余容量
bash
for((i=1;i<=10;i--)) { desk_free=$(df -h | awk -F " " '{print $4}' | sed -n '6p') if [ $desk_free -lt 20000 ] then echo "磁盘容量不足!" # 发送给指定邮箱 elif [ $desk_free -lt 5000 ] then reboot fi sleep 2 # 休眠 }示例3:自动化备份
bash
# 流程:将备份目录压缩成包 → 把包丢到备份目录 → 删除历史备份包 date=$(date +"%Y%m%d") tar -zcvf $date".tar.gz" /home/hadoop/2608 mkdir -p /home/hadoop/backup mv $date".tar.gz" /home/hadoop/backup find /home/hadoop/backup -type f -mtime +7 | xargs rm -rf
示例4:自动化巡检服务日志
bash
find /opt/module/hadoop-3.3.0/logs -name "*.log" | while read line; do err_num=$(grep "error" $line | wc -l) if [ $err_num -eq 0 ] then echo $line"是没有报错的!" else echo $line"有报错,错误信息,请在 /home/hadoop/1111/err.txt 查阅!" grep "error" $line >> /home/hadoop/1111/err.txt fi done
Shell 脚本的入参
参数变量
| 变量 | 含义 |
|---|---|
$0 | 被调用的脚本文件名 |
$1 | 第一个入参值 |
$2 | 第二个入参值 |
$3 | 第三个入参值 |
$* | 所有的入参集合 |
$# | 入参的个数 |
$? | 判断上一个命令返回的布尔值(真则返回0,否则返回1) |
调用方式
bash
sh shell脚本名 入参1 入参2 入参3 ...常见面试问答
Q:开发过什么功能性的Shell脚本?
A:开发过一些自动化备份、打包、巡检等相关的脚本,也封装过一些数据库的脚本执行。