Linux Shell脚本讲解
目录
Shell脚本基础
Shell脚本组成
Shell脚本工作方式
编写简单的Shell脚本
Shell脚本参数
Shell脚本接收参数
Shell脚本判断用户参数
文件测试与逻辑测试语句
整数测试比较语句
字符串比较语句
Shell流程控制
if条件判断语句
单分支
双分支
多分支
for循环语句(根据范围进行循环)
while循环语句(根据条件进行循环)
case条件测试语句(判断语句)
Shell脚本编写计划任务
一次性计划任务
长期性计划任务
Shell脚本基础
Shell脚本组成
Shell脚本由三部分组成
脚本声明、脚本注释、脚本命令
脚本声明
告诉系统我们是使用哪个解释器来执行Shell脚本
现在基本上都是使用/bin/bash解释器
所以一般脚本声明为 #!/bin/bash
脚本注释
写一些说明信息(包括功能介绍、参数介绍等,可有可无)
此注释不会被系统读,只是让用户看的
#开头
脚本命令
通过这些命令来完成某些事情
Shell脚本工作方式
交互式 用户每输入一条命令就立即执行
批处理 用户事先编写一个完整的Shell脚本,Shell就会一次性执行脚本中的命令
编写简单的Shell脚本
简单的Shell脚本可以理解为就是命令的堆积,能够实现一些固定的功能
没有调节测试语句、循环语句赋予的灵活的调节判断功能
创建Shell脚本
shell脚本可以没有后缀,但是为了区分,可以给个后缀.sh
vim 123.sh 创建/编辑 名称为123的Shell脚本
编写简单的Shell脚本
#!/bin/bash 编写脚本声明
#this is test 编写脚本注释
pwd 编写脚本显示当前位置
grep /bin/bash /etc/passwd | wc -l 编写脚本显示可登录服务器的用户数量
执行Shell脚本
. 123.sh 路径+Shell脚本名,直接执行 Shell脚本(用户需要执行权限,可以更改权限)
. 表示当前路径
bash 123.sh bash shell脚本名称,通过bash命令调用Shell脚本
Shell脚本参数
Shell脚本接收参数
为了让Shell脚本程序更好地满足用户的一些实时需求
需要让脚本程序能够像之前执行命令那样接收用户的参数
此时就需要向Shell脚本传递参数
Shell脚本如何接收用户参数
在Shell脚本通过定义$N来接受用户输入的参数
$1、接收第一个位置参数
$2 接收第二个位置参数
Shell脚本的特殊参数
$0 脚本的名称
$# 统计接收参数的总数(用户输入的所有参数的总数)
$* 接收到的所有参数有哪些(用户输入的所有参数)
编写Shell脚本接收用户参数
编写Shell脚本
#!/bin/bash
#this is test
echo $1,$2,$4 接收用户输入的第1、2、4个参数并输出
echo "neame is $0" 显示脚本的名称
echo "count receive parameter number is $#" 统计用户输入的参数总数
echo "all receive parameter is $*" 用户输入的参数具体有哪些
执行脚本并输入参数
bash 123.sh 1 2 3 4 5
Shell脚本判断用户参数
判断语句格式:[ 条件表达式 ](注意条件表达式前后都有空格)
由于变量是没有定义类型的
在Shell中需要对输入的参数、变量进行类型判断(需要手动去完成,通过创建条件表达式完成)
根据测试对象的不同,条件表达式可分为以下4种
文件测试语句、逻辑测试语句(查看判断结果)、整数值比较语句、字符串比较语句
文件测试与逻辑测试语句
作用
判断文件是否存在
判断是什么类型的文件(一般文件、目录文件、设备(块)文件、链接文件、管道文件)
判断文件权限(写入、读取、执行权限)
具体操作符
[ -e 文件名称 ] 判断文件是否存在
[ -f 文件名称 ] 判断文件是否为一般文件(-d 目录文件、-l 链接文件、-s 套接字文件、-b块设备文件、-c 字符设备文件、-p 管道文件)
[ -w 文件名称 ] 判断文件的权限是否可以写入(-r是否可以读取、-x是否可以执行)
进行判断后如何得到判断结果
方一 通过echo$? 来得到判断结果
echo $? 输出上一个返回值的结果(可以用此命令来查看判断文件的结果)
如果结果为0,表示上一个命令执行成功;非零表示上一个命令执行失败
此方法要使用两条命令查看,麻烦
方二 通过逻辑测试语句(逻辑操作操作符)来查看判断结果
与(&&) 前面的语句如果执行成功,执行后面的语句
或(||) 前面的语句如果执行失败,执行后面的语句
非(!) 取反值(! 代表取反值;!=代表不等于)
[ -e 文件名 ] && 命令 如果文件存在,就执行命令
[ ! -e 文件名 ] 将文件是否存在的结果取反
编写文件判断Shell脚本
#!/bin/bash
#this is test
[ -e /dev/fastab ] 判断/dec/fstab文件是否存在
echo "this file $?" 输出上一个判断文件执行结果
[ $USER=root ] && echo " be" || “no be” 如果当前用户为root,输出be,否则输出no be
整数测试比较语句
对于数字比较所使用的操作符不能用>、<,因为>、<是重定向符
数据比较通过操作符 -eq、-gt、-lt等来执行
[ 1 -eq 2 ] 判断1是否等于2
[ 1 -gt 2 ] 判断1是否大于2
[ 1 -lt 2 ] 判断1是否小于2
-ne 是否不等于
-le 是否等于或小于
-ge 是否大于或等于
编写整数比较语句
#!/bin/bash
#this is test
FREE=`free -m | grep Mem | awk '{print $4}'` 将空闲内存的值赋值给变量FREE
[ $FREE -le 1024 ] && echo "$FREE is good" || echo "$FREE is bad"
比较空闲内存大小,小于等于1024为good,否则为bad
字符串比较语句
-z 判断字符串内容是否为空
!= 比较字符串内容是否不同
= 比较字符串内容是否相同
编写字符串比较语句
#!/bin/bash
#this is test
[ -z $USER=root ] 判断当前用户是否为是root
echo $?
[ ! -z $USER=root ] 判断当前用户是否不是root
echo $?
Shell流程控制
if条件判断语句
if 条件测试语句(if开头,fi结尾),可以分为单分支、双分支、多分支
单分支
语句格式
if 测试条件
then 条件通过所执行的命令(可以多条,如果在同一行用 ; 分隔多条命令)
fi
编写单分支脚本
#!/bin/bash
if [ ! -e /etc/admin ] 判断/etc/admin是不是不存在
then mkdir -p /etc/admin 如果不存在,则创建/etc/admin
echo `[ -e /etc/admin ] && echo 'create success'` 然后再判断/etc/admin是否创建成功
fi
双分支
语句格式
if 测试条件
then 条件通过所执行的操作
else 条件没有通过执行的操作
fi
编写双分支脚本
#!/bin/bash
if [ ! -e /etc/admin ] 判断/etc/admin是不是不存在
then mkdir -p /etc/admin ; echo `[ -e /etc/admin ] && echo 'create success'` 如果文件不存在,创建文件并判断文件是否创建成功
else echo 'this file is be' 如果文件存在,则输出this file is be
fi
多分支
语句格式
if 测试条件1
then 条件1通过后执行的操作
elif 测试条件2
then 条件2通过后执行的操作
else
条件1和条件2都不满足的操作
fi
多分支编程
#!/bin/bash
read -p "input number: " NUMBER 将用户输入的数据赋值到变量NMBER
if [ $NUMBER -ge 80 ] && [ $NUMBER -le 100 ];then 判断值是否≥80,≤100
echo 'good' 输出
elif [ $NUMBER -ge 60 ] && [ $NUMBER -le 79 ];then 判断值是否≥60,≤79
echo 'pass'
elif [ $NUMBER -ge 0 ] && [ $NUMBER -le 59 ] ;then 判断值是否≥0,≤59
echo 'fail'
else 以上条件都不满足
echo 'again input'
read -p "Enter:" GRADE
read 变量 读取单行数据内容,并将此内容赋值给变量GRADE
-p 提示用户输入信息
注意:字母与数字不能够作比较,小数也不可以和整数比较
for循环语句(根据范围进行循环)
语句格式
for 变量名 in 取值列表
do
操作命令
done
编写for循环语句
#!/bin/bash
read -p "input passwd: " PASSWD 输入密码并赋值到变量PASSWD
for USER1 in `cat user.txt` 从文件中提取数据赋值到变量USER1
do
id $USER1 &> /dev/null 查看用户信息并将回显的内容送到黑洞
if [ $? -eq 0 ];then 如果用户存在,即上个命令执行成功,输出用户is be
echo "$USER1 is be"
else 如果用户不存在,上个命令执行就不成功,执行以下命令
useradd $USER1 &> /dev/null
echo $PASSWD | passwd --stdin $USER1 &> /dev/null
fi
done
while循环语句(根据条件进行循环)
只要条件为真,则一直循环,只要条件不成立,才会停止
语句格式
while 条件
do 执行操作
done
while true 一直循环下去,直到遇到强制退出符
case条件测试语句(判断语句)
语句格式
case 变量值 in 范围值1)
输出命令1
;;
范围值2)
输出命令2
;;
*)
默认命令
esac
注意
case 命令只有右边的小括号,没有左边的小括号
case语句中的 | 指的是 逻辑或 的意思
* 匹配的是空值或者无穷多的信息
前面的范围值后面要加;; 最后的范围值不需要加;;
编写case判断语句
#!/bin/bash
read -p "input :" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "$KEY this is letter"
;;
[0-9])
echo "$KEY this is number"
;;
*)
echo "$KEY this is ohter characters"
esac
Shell脚本编写计划任务
管理员可以编辑自己的和普通用户的计划任务
普通用户只可以编辑自己的计划任务
计划任务根据执行方式分为一次性计划任务、长期性计划任务
一次性计划任务
此计划只执行一次,执行后或就不会再执行了
通过at命令来实现
at 时间
输入想要执行的任务
ctrl + d 保存并退出
ctrl + c 直接退出
at -c 任务编码 查看计划任务的工作
at -l 显示待执行的任务列表(显示任务编号 任务执行时间 发起用户)
at -d 任务编码 删除指定待执行任务
at -m 任务执行后给用户发邮件
at now +5 MINUTE 创建任务,5分钟后执行(HOUR时、DAY天、MONTH月)
atrm命令
atrm 任务编码 删除计划任务
长期性计划任务
长期性计划任务,周期性的根据时间规则执行任务
时间规则格式-此格式是固定的,如果不配置参数,需要使用*来做占位
分、时、日、月、星期 、命令
其中命令的使用方式必须是 命令路径方式(可以通过which来进行查找)
即ls -l 需要写为 /usr/bin/ls -l
例子:
10 21 12 * * 命令 每月的12号21点10分执行任务
* * * */2 * 命令 当下开始每间隔两个月
* * * 1,2,3 * 命令 1、2、3个月
* * * 1-5 * 命令 1到5个月
一般星期和日期只选择一个进行书写
crontab命令
长期计划任务通过Linux的crond服务来实现
而crond服务需要通过crontab命令来进行配置
即:crond是服务名称、crontab是配置工具名称
需要开启crond服务
systemctl enable crond 开启crond服务
systemctl restart crond 重新启动crond服务
如果配置了计划之后没有生效,可以重新启动下服务
命令格式
crontab -e 创建/编辑计划任务
crontab -l 指定计划任务
crontab -r 删除计划任务
也可以直接通过命令路径的方式编辑计划
vim /etc/crontab 来创建/编辑计划任务
不过不推荐使用vim进行编辑,虽然有注释,但是没有纠错功能
使用crontab有纠错功能,不过crontab 默认也是通过调用vim编译器来实现的
注意事项
当普通用户使用at和crontab不起作用时,不一定是计划任务的原因
还可能是用户权限的问题