一、入门案例及运行方法
编写一个输出语句的shell脚本,注意:脚本必须以#!/bin/bash
开头,其中#
和:<<! !
是注释方法。
首先我们可以看出该shell脚本没有执行权限
目前这个状态只能通过sh demo.sh
来运行:
或者给该文件加上执行权限,再直接运行:
二、变量
Linux Shell 中的变量分为,系统变量和用户自定义变量。
系统变量: H O M E 、 HOME、 HOME、PWD、 S H E L L 、 SHELL、 SHELL、USER 等等,比如: echo $HOME 等等…
查看系统变量:
通过set可以看到当前shell的所有变量:
1.自定义变量案例:
#!/bin/bash
#案例 1:定义变量A
A=100
#输出变量需要加上$
echo A=$A
echo "A=$A"
#案例 2:撤销变量A
unset A
echo "A=$A"
#案例 3:声明静态的变量 B=2,不能 unset
readonly B=2
echo "B=$B"
#unset B
#将指令返回的结果赋给变量 :
C=`date`
D=$(date)
echo "C=$C"
echo "D=$D"
#使用环境变量 JAVA_HOME
echo "java_home=$JAVA_HOME"
如果撤销变量b会报异常!
2.设置环境变量,其实上面的JAVA_HOME
就是在/etc/profiles
文件中设置的
#(功能描述:将 shell 变量输出为环境变量/全局变量)
export 变量名=变量值
#(功能描述:让修改后的配置信息立即生效)
source 配置文件
# (功能描述:查询环境变量的值)
echo $变量名
比如我在demo.sh中新增下面的一行,并用source语句刷新
我们发现linux系统已经能识别A这个全局变量了!
3.位置参数变量
#!/bin/bash
echo "0=$0 1=$1 2=$2"
echo "所有参数=$*" #会把所有参数看成一个整体
echo "所有参数=$@" #会把所有参数分开
echo "参数个数=$#"
4.预定义变量
$$
功能描述:当前进程的进程号(PID))
$!
(功能描述:后台运行的最后一个进程的进程号(PID))
$?
(功能描述:最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变 量的值为非 0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。)
#!/bin/bash
echo "当前执行的进程 id=$$"
#以后台的方式运行一个脚本,并获取他的进程号
/luzelong/shellcode/demo.sh &
echo "最后一个后台方式运行的进程 id=$!"
echo "执行的结果是=$?"
三、运算符
a=$((运算式))
b=$[运算式]
#注意 expr 运算符间要有空格,乘号要写成 \*
c='expr m + n'
案例演示:
#!/bin/bash
#案例 1:计算(2+3)X4 的值 #使用第一种方式
RES1=$(((2+3)*4))
echo "res1=$RES1"
#使用第二种方式, 推荐使用
RES2=$[(2+3)*4]
echo "res2=$RES2"
#使用第三种方式 expr
TEMP=`expr 2 + 3`
RES4=`expr $TEMP \* 4`
echo "temp=$TEMP"
echo "res4=$RES4"
#案例 2:请求出命令行的两个参数[整数]的和 20 50
SUM=$[$1+$2]
echo "sum=$SUM"
四、条件判断
#非空返回 true,可使用$?验证(0 为 true,>1 为 false)
[ condition ](注意 condition 前后要有空格)
#条件满足,执行后面的语句
[condition]&&echoOK||echonotok
常用判断条件
- = 字符串比较
- 两个整数的比较
-lt 小于
-le 小于等于 little equal -eq 等于
-gt 大于 -ge 大于等于 -ne 不等于- 按照文件权限进行判断
-r 有读的权限 -w 有写的权限 -x 有执行的权限- 按照文件类型进行判断
-f 文件存在并且是一个常规的文件 -e 文件存在
-d 文件存在并是一个目录
#!/bin/bash
#案例1:"ok"是否等于“ok”
if [ "ok" = "ok" ]
then
echo "相等"
fi
#案例2:判断23是否大于等于22
if [ 23 -ge 22 ]
then
echo "大于"
fi
#案例3: /luzelong/shellcode/demo.sh 是否存在
if [ -f /luzelong/shellcode/demo.sh ]
then
echo "存在"
fi
#其他案例
if [ luzelong ]
then
echo "hello,luzelong!"
fi
五、流程控制
1.if判断实现流程控制
#!/bin/bash
#案例:请编写一个shell程序,如果输入参数大于等于60,则输出及格了,否则输出不及格
if [ $1 -ge 60 ]
then
echo "及格了"
elif [ $1 -lt 60 ]
then
echo "不及格"
fi
2.case语句实现流程控制
#!/bin/bash
#案例:当命令行参数是1时,输出周一,参数是2时,输出周二,参数为其他时,输出other..
case $1 in
"1")
echo "周一"
;;
"2")
echo "周二"
;;
*)
echo "other..."
;;
esac
六、循环语句
1.for循环
#!/bin/bash
#案例1:打印命令行输入的参数[这里可以看出$*和$的区别]
#注意$*是把输入的参数,当做一个整体,所以,只会输出一句
for i in "$*"
do
echo "num is $i"
done
echo "================================"
#使用$@来获取输入的参数,注意,这时是分别对待,所以有几个参数,就输出几行
for i in "$@"
do
echo "num is $i"
done
#!/bin/bash
#案例2:算0加到100的值
SUM=0
for(( i=1;i<=100;i++))
do
SUM=$[$SUM+$i]
done
echo "总和SUM=$SUM"
2.while循环
#!/bin/bash
#案例:从命令行输入一个数n,统计1+2+...+n的值
SUM=0
i=0
while [ $i -le $1 ]
do
SUM=$[$SUM+$i]
#i自增
i=$[$i+1]
done
echo "执行结果=$SUM"
七、read读取控制台输入
#!/bin/bash
#案例1:读取控制台输入一个NUM1值
read -p "请输入一个数NUM1=" NUM1
echo "你输入的NUM1=$NUM1"
#案例2:读取控制台输入一个NUM2值,在10s内输入
read -t 10 -p "请输入一个数NUM2=" NUM2
echo "你输入的NUM2=$NUM2"
八、函数
1.系统函数
#basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
#suffix 为后缀,如果suffix 被指定了,basename会将 pathname 或 string 中的 suffix 去掉。
basename [pathname] [suffix]
#从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩 下的路径(目录的部分)
dirname /home/aaa/test.txt
2.自定义函数
#!/bin/bash
#案例 1:计算输入两个参数的和(动态的获取), getSum
#定义函数 getSum
function getSum() {
SUM=$[$n1+$n2]
echo "和是=$SUM"
}
#输入两个值
read -p "请输入一个数 n1=" n1
read -p "请输入一个数 n2=" n2 #调用自定义函数
getSum $n1 $n2
九、经典的综合案例
比如我要完成下面的功能:
1)每天凌晨2:30备份数据库jjy到/data/backup/db
2)备份开始和备份结束能够给出相应的提示信息
3)备份后的文件要求以备份时间为文件名,并打包成.tar.gz的形式,比如:2021-03-12_230201.tar.gz4)在备份的同时,检查是否有10天前备份的数据库文件,如果有就将其删除。
1.创建数据库
具体的shell代码如下:
#!/bin/bash
#备份目录
BACKUP=/data/backup/db
#当前时间
DATETIME=$( date +%Y-%m-%d_%H%M%S )
echo $DATETIME
#数据库的地址
HOST=localhost
#数据库用户名
DB_USER=root
#数据库密码
DB_PW=luzelong1124
#备份的数据库名
DATABASE=jjy
#创建备份目录,如果不存在,就创建
[ ! -d "${BACKUP}/${DATETIME}" ] && mkdir -p "${BACKUP}/${DATETIME}"
#备份数据库
mysqldump -u${DB_USER} -p${DB_PW} --host=${HOST} -q -R --databases ${DATABASE} | gzip > ${BACKUP}/${DATETIME}/$DATETIME.sql.gz
#将文件处理成tar.gz
cd ${BACKUP}
tar -zcvf $DATETIME.tar.gz ${DATETIME}
#删除对应的备份目录
rm -rf ${BACKUP}/${DATETIME}
#删除10天前的备份文件
find ${BACKUP} -atime +10 -name "*.tar.gz" -exec rm -rf {} \;
echo "备份数据库${DATABASE}成功~"
如果单独执行,则是下面的运行情况:
如果想要每天凌晨2点半定时执行该任务则需要用到crontab -e
语句