shell编程
一、Shell介绍
shell是一个命令行解释器,它为用户提供了一个向linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。
硬件---内核---shell----外层应用程序
二、shell脚本的执行方式
'''
- 格式要求:
1.脚本以 #!/bin/bash 开头
2.脚本要有可执行权限
- 执行方式
方式一:
1.赋予脚本文件的+x权限
2.执行脚本
方式二:(推荐使用第一种)
bash 脚本文件路径
sh 脚本路径
'''
三、shell变量
'''
shell变量介绍:
- shell变量分为系统变量和用户自定义变量
- 系统变量:$HOME,$PWD,$SHELL,$USER 等等
- 显示当前shell中所有变量: set
shell变量定义:
1.定义变量:
变量名 = 值
2.撤销变量
unset 变量名
3.声明静态变量(不能unset)
readonly 变量名
变量名的定义规则:
1.变量名称可以由字母、数字和下划线组成,但是不能以数字开头
2.等号两侧不能有空格
3.变量名称一般习惯大写
将命令的返回值赋值给变量
A=`ls -la` 反引号,运行里面的命令,并把结果返回给变量
A=$(ls -la) 等价于反引号
'''
myshell.sh
#! /bin/bash
echo "user=$USER"
echo "path=$PATH"
A=10
echo "A=$A"
unset A
echo "A=$A"
readonly A=10
echo "A=$A"
unset A # 会报错,静态变量不能unset
MY_DATE=`date`
echo "date=$MY_DATE"
RESULT=$(ls -l)
echo $RESULT
四、设置环境变量
'''
基本语法:
- export 变量名=变量值 (将shell变量输出为环境变量)
- source 配置文件 (让修改后的配置信息立即生效)
- echo $变量名
'''
/etc/profile
....
# 自定义环境变量
TOMCAT=/opt/tomcat
export TOMCAT
# 多行注释
:<<!
TOMCAT=/opt/tomcat
export TOMCAT
!
五、位置参数变量
'''
介绍:当我们执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量。比如:./myshell.sh 100 200这个就是一个执行shell命令行,可以在myshell 脚本中获取到参数信息。
基本语法:
- $n 功能描述:n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,10及10以上的参数需要用大括号例如:${10}
- $* 功能描述:这个变量代表命令行中的所有参数,$*把所有参数看成一个整体(不包含$0)
- $@ 功能描述:这个变量也代表命令行中所有参数,不过$@把每个参数区分对待
- $# 功能描述:这个变量代表命令行中所有参数的个数
'''
应用实例:
1.编写一个shell脚本postion.sh,在脚本中获取命令行的各个参数信息
#! /bin/bash
echo $*
echo $@
echo "参数个数=$#"
六、预定义变量
'''
基本介绍:就是shell设计者实现已经定好的变量,可以直接在shell脚本中使用。
基本语法:
$$ 功能描述:当前进程的进程号(PID)
$! 功能描述:后台运行的最后一个进程的进程号(PID)
$?功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值不是0,则证明上一个命令执行不正确。
'''
案例使用
#! /bin/bash
echo "当前进程号为:$$"
./myshell22.sh &
echo "后台运行的最后一个进程号:$!"
echo "最后一个命令:$?"
七、运算符
'''
基本介绍:
学习如何在shell中使用各种运算操作
基本语法:
1)"$((运算式))" 或 "$[运算式]"
2)expr m + n (注意expr运算符之间要有空格)
3)expr m - n
4)expr \* / % 乘,除,取余
'''
使用案例
#!/bin/bash
RESULT=$[3 + 2]
echo $RESULT
# 第一种方式()
RESULT1=$(((2+3)*4))
echo $RESULT
# 第二种方式[]
RESULT2=$[(2+3)*4]
echo $RESULT2
# 第三种方式expr
TEMP=`expr 10 + 20`
RESULT3=`expr $TEMP \* 10`
echo $RESULT3
八、条件判断
'''
基本语法:
[ condition ] (注意conditon前后都要空格)
# 非空返回true,可使用$?验证(0位true,>1位false)
常用判断条件:
1.两个整数比较
= 字符串比较
-lt
-le
-eq
-gt
-ge
-ne 不等于
2.按照文件权限进行判断
-r
-w
-x
3.按照文件类型进行判断
-f 文件存在并且是一个常规的文件
-e 文件存在
-d 文件存在并且是一个目录
'''
应用实例
#!/bin/bash
#1.“ok”是否等于“ok”
if [ "ok" = "ok" ]
then
echo "equal"
fi
#2.23是否大于等于22
if [ 23 -gt 22 ]
then
echo "大于"
fi
#3.判断某个文件是否存在
if [ -e /root/shell/aaa.txt ]
then
echo "存在"
fi
九、流程控制之if
'''
基本语法:
if [ condition ];then
程序
fi
# 或者
if [ condition ]
then
程序
elif [ condition ]
then
程序
fi
'''
使用案例
# 60分和60分以上及格,60分以下不及格
if [ $1 -ge 60 ]
then
echo "及格了"
elif [ $1 -lt 60 ]
then
echo "不及格"
fi
十、流程控制之case
'''
基本语法:
case $变量 in
"值1")
变量值==值1的时候执行的语句
;;
"值2")
变量值==值2的时候执行的语句
;;
*)
如果变量的值都不是以上值时执行的语句
;;
'''
使用案例
#!/bin/bash
# 命令行参数是1输出周一,是2输出周二,其他情况输出other
case $1 in
"1")
echo "周一"
;;
"2")
echo "周二"
;;
*)
echo "other"
;;
esac
十一、流程控制之for循环
'''
基本语法1:
for var in val1 val2 val3
do
程序
done
基本语法2:
for ((初始值;循环控制条件;变量变化))
do
程序
done
'''
使用案例1
#!/bin/bash
# 打印命令行输入的参数
# $*的情况
for i in "$*"
do
echo "the num is $i"
done
# $@的情况
for j in "$@"
do
echo "the num is $j"
done
使用案例2
#!/bin/bash
SUM=0
for ((i=0;i<=100;i++))
do
SUM=$[$SUM+$i]
done
echo "$SUM"
十二、流程控制之while循环
'''
基本语法
while [ condition ]
do
程序
done
'''
使用案例
#!/bin/bash
# 输入一个n,输出1+2...+n的值
i=0
SUM=0
# 这里的[]是条件判断,所以左右需要空格
while [ $i -le $1 ]
do
SUM=$[$SUM+$i] #这里的[]是运算式
i=$[$i+1]
done
echo "$SUM"
十三、READ读取控制台输入
'''
基本语法:
read (选项)(参数)
选项:
-p:指定读取值时的提示符
-t:指定读取值时等待的时间(秒),如果没有在指定的时间内输入就不再等待了
参数:
变量:指定读取值时的变量名
'''
使用案例
#!/bin/bash
read -p "请输入一个数num1=" NUM1
echo "你输入的值是num1=$NUM1"
read -t 10 -p "请输入一个数num2=" NUM2
echo "你输入的值是num2=$NUM2"
十四、函数
'''
shell编程和其它编程语言一样,有系统函数,也可以自定义函数。
简单介绍两个系统函数:
1.basename
功能:返回完整路径最后/的部分,场用于获取文件名
basename[pathname][suffix]
basename[string[suffix]] (功能描述:basename命令会删除掉所有的前缀包括最后一个'/'字符,然后将字符串显示出来)
2.dirnane
功能:返回完整路径最后/的前面的部分,常用语返回路径部分
dirname 文件绝对路径(功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录部分),然后返回剩下的路径(目录的部分))
dirname /home/test.txt ===> /home
'''
使用案例
#!/bin/bash
basename /home/aaa.txt
basename /home/aaa.txt .txt
十五、自定义函数
'''
[]里的内容可写可不写
[ function ]funcname[()]
{
Action;
[return int;]
}
调用直接写函数名:funcname
'''
使用案例
#!/bin/bash
function getSum()
{
SUM=$[$n1+$2];
echo "和是=$SUM"
# return int $SUM;
}
read -p "请输入第一个数n1" n1
read -p "请输入第二个数n2" n2
# 调用getSum
getSum $n1 $n2
综合使用案例
'''
1.每天凌晨2:10备份数据库atguiguDB 到/data/backup/db
2.备份开始和备份结束能够给出相应的提示信息
3.备份后的文件要求以备份时间为文件名,并打包成.tar.gz的形式,比如
2020-02-02_230201.tar.gz
4.在备份的同事,检查是否有10天前备份的数据库文件,如果有就将其删除
'''
#!/bin/bash
BACKUP="/data/backup/db"
DATETIME=$(date "+%Y-%m-%d_%H%M%S")
echo "=========开始备份========"
echo "=========备份的路径是$BACKUP/$DATETIME.tar.gz"
# 主机
HOST=localhost
# 用户名
DB_USER=root
# 密码
DB_PWD=root
# 要备份的数据库名
DATABASE=testDB
# 创建备份的路径
[ -d "$BACKUP/$DATETIME" ]&& mkdir -p "$BACKUP/$DATETIME"
# 执行mysql的备份数据库指令
mysqldump -u${DB_USER} -p${DB_PWD} --host=$HOST $DATABASE | gzip >$BACKUP/$DATETIME/$DATETIME.sql.gz
# 打包备份文件
cd $BACKUP
tar -zcvf $DATETIME.tar.gz $DATETIME
# 删除临时目录
rm -rf $BACKUP/$DATETIME
# 删除10天前的备份文件
find $BACKUP -mtime +10 -name "*.tar.gz" -exec rm -rf {} \;
echo "=========备份文件成功=========="