1.Shell简介
shell的用途
Linux运维工程师通过shell程序对服务器进行集群管理。
JavaEE和Python程序员编写Shell脚本对服务器进行维护,比如定时备份数据库
等等…
Shell是什么?
Shell是一个命令行解释器,它为用户提供了一个Linux内核发送请求以便运行程序的界面系统级程序,用户可以使用Shell来启动,挂起,停止甚至是编写一些程序。
shell—->内核—->硬件
脚本格式要求
脚本以#!/bin/bash开头
脚本需要有可执行权限
shell快速入门
创建一个shell脚本,输出hello world!
[root@localhost shelltest]# vim hello.sh
#!/bin/bash echo "hello world!"
执行方式
通常使用方式1
方式1 (输入脚本的绝对路径或者相对路径)
首先赋予hello.sh脚本的+x权限
执行脚本
[root@localhost shelltest]# chmod 744 hello.sh [root@localhost shelltest]# ./hello.sh hello world! [root@localhost shelltest]# /root/shelltest/hello.sh hello world!
方式2 (sh+脚本)
不赋予脚本+x权限,直接执行
[root@localhost shelltest]# sh ./hello.sh hello world!
2.shell变量
介绍
分为系统变量和用户自定义变量
系统变量:$HOME ,$PATH,$USER等
echo $HOME
显示shell中所有变量 set
变量的定义
变量=值
撤销变量:unset 变量
声明静态变量 readonly 变量
例:
#!/bin/bash #echo "hello world!" A=100 echo "自定义变量与销毁" echo "A= $A" unset A echo "A=" echo "声明静态变量" readonly B=111 echo "B=$B" #unset B #报错,静态变量不能unset
变量定义的规则
变量名称可以由字母,数字或者下划线组成,不能以数字开头
变量赋值时等号两侧不能有空格
变量名称一般习惯为大写
将命令的返回值赋给变量
①A= ls -la `反引号 ,运行里面的命令,并把结果返回给变量A
②A=$(ls -la ) 等价于反引号
RESULT=`ls -l /home` echo $RESULT echo "" A=$(date) echo $A
3.设置环境变量
基本语法
export 变量名=变量值 (将shell变量输出为环境变量)
source 配置文件 (让修改后的配置信息立即生效)
echo $变量名 (查询环境变量的值)
快速入门
在/etc/profile文件中定义TOMCAT_HOME环境变量
vim /etc/profile
#定义一个自己的环境变量 TOMCAT_HOME=/opt/tomcat/ export TOMCAT_HOME
查看环境变量TOMCAT_HOME的值
[root@localhost shelltest]# source /etc/profile [root@localhost shelltest]# echo $TOMCAT_HOME /opt/tomcat/
在另外一个shell程序中使用TOMCAT_HOME
多行注释 :<<! 注释内容!
#!/bin/bash #使用自定义的环境变量 echo $TOMCAT_HOME [root@localhost shelltest]# ./hello.sh /opt/tomcat/
注意: 为了让/etc/profile的环境变量生效,需要使用 source /etc/profile
重启系统或者注销用户
4.位置参数变量
介绍
当执行一个shell 脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量
比如 ./myshell.sh 100 200 这个就是一个执行shell的命令行 ,可以在myshell中获取参数信息
基本语法
$n :n为数字,$0代表命令本身,$1-$9代表第一个参数到第九个参数,十以上的参数需要用大括号包含,{$10}
$* :这个变量代表命令行中的所有参数,$把所有的参数看成*一个整体**
$@ : 这个变量也代表命令行中的所有参数,但是$@把每个参数 区分对待
$# : 这个变量代表命令行中所有参数的个数
实例
写一个shell脚本,positionPara.sh 在脚本中获取到命令行的各个参数信息
#!/bin/bash #获取各个参数 echo "命令行参数 0,1,2 $0 $1 $2" echo "*: $*" echo " @:$@" echo "参数个数=$#"
[root@localhost shelltest]# chmod 744 positionPara.sh [root@localhost shelltest]# ./positionPara.sh 30 60 命令行参数 0,1,2 ./positionPara.sh 30 60 *: 30 60 @:30 60 参数个数=2
5.预定义变量
介绍:
shell的设计者事先定义好的变量,可以直接在shell脚本中使用
基本语法
$ $ :当前进程的进程号
$!:后台运行的最后一个进程的进程号
$? :最后一次执行的命令的返回状态。如果变量的值为0,证明上一个命令正确执行;如果变量的值为非0(具体是哪个数字,由命令自己决定),则证明上一个命令执行不正确
简单使用预定义变量
vim prevar.sh
#!/bin/bash echo "当前的进程号=$$" #后台的方式运行 hello.sh ./hello.sh & echo "最后的进程号=$!" echo "执行的值=$?"
[root@localhost shelltest]# ./prevar.sh 当前的进程号=3068 最后的进程号=3069 执行的值=0
Ctrl+c 退出
6.运算符
基本语法
$((运算式)) 或 $[运算式]
expr m + n 注意expr 运算符间要有空格
expr m - n expr \* /,% 乘,除,取余
实例
计算 (2+3)*4
#!/bin/bash ans1=$(((2+3)*4)) ans2=$[(2+3)*4] echo "ans1=$ans1" echo "ans2=$ans2"
请求出命令行的两个参数和
ans3=$[$1+$2] echo "命令行两个参数的和为 $ans3"
[root@localhost shelltest]# ./test.sh 20 40 ans1=20 ans2=20 命令行两个参数的和为 60
7.条件判断
基本语法
[ condition ] condition前后要有空格
常用判断条件
= 字符串比较
-lt 小于
-le 小于等于
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
按照文件权限判断
- r 有读的权限
-w 有写的权限
-x 有执行的权限
按照文件的类型判断
-f 文件存在并且是一个常规文件
-e 文件存在
-d 文件存在并且是一个目录
案例
ok是否等于ok
[root@localhost shelltest]# vim condition.sh
#!/bin/bash if [ "ok"="ok" ] then echo "equal" fi if [ 23 -gt 22 ] then echo "大于" fi #判断文件是否存在 if [ -e /root/shelltest/aaa.txt ] then echo "存在" fi #文件权限 if [ -r /root/shelltest/aaa.txt ] then echo "有读的权限" fi
[root@localhost shelltest]# chmod 744 condition.sh [root@localhost shelltest]# ./condition.sh equal 大于 存在 有读的权限
删除某个目录下的空文件,并且名字以u开头
#!/bin/bash for filename in `find /home/ -name "u*" -type d -empty ` do echo $filename echo `rm -rf $filename` done
8.流程控制
if判断
if [ 条件判断 ]; then
程序
fi
或者
if [ 条件判断 ]
then
程序
elif [ 条件判断式 ]
then
程序
fi
案例
#!/bin/bash if [ $1 -ge 60 ] then echo "及格" elif [ $1 -lt 60 ] then echo "不及格" fi
[root@localhost shelltest]# ./testif.sh 78 及格
case语句
#!/bin/bash case $1 in "1") echo "周一" ;; "2") echo "周二" ;; *) echo "other" ;; esac
for 循环
for 变量 in 值1 值2 值3 …
do
程序
done
或者
for ((初始值;循环控制条件;变量变化))
do
程序
done
案例:
#!/bin/bash #打印命令行输入的参数 #使用$* for i in "$*" do echo "the num is $i" done echo "------------" #使用 $@ for j in "$@" do echo "the num is $j" done
[root@localhost ~]# ./printpara.sh 25 23 45 the num is 25 23 45 ------------ the num is 25 the num is 23 the num is 45
#!/bin/bash #100以内的整数和 sum=0 for ((i=1;i<=100;i++)) do sum=$[$sum+$i] done echo "100以内的整数和: $sum"
while循环
while [ 条件判断式 ]
do
程序
done
案例:
#!/bin/bash #从命令行接收参数,输出1---的值 sum=0 i=0 while [ $i -le $1 ] do sum=$[$sum+$i] i=$[$i+1] done echo "值为: $sum"
9.read读取控制台输入
基本语法
read [选项] [参数]
选项:
-p : 指定读取值时的提示符
-t :指定读取值时的等待时间(秒),如果在没有指定的时间内输入,就不再等待了。
参数:
变量:指定读取值的变量名
实例
#!/bin/bash #读取控制台输入的num值 read -p "请输入一个数: " NUM1 echo "第一个值为: $NUM1" #读取控制台输入的num2值,要求在10s内输入 read -t 10 -p "请在10秒内输入第二个数: " NUM2 echo "第二个数为: $NUM2"
10.函数
系统函数
basename 基本语法
功能:返回完整路径最后/的部分,常用于获取文件名
basename [pathname] [suffix]
basename [string] [suffix] 删除所有前缀,包括最后一个‘/‘,字符,然后将字符串显示出来
suffix为前缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
实例:
[root@localhost ~]# basename /root/shelltest/aaa.txt aaa.txt [root@localhost ~]# basename /root/shelltest/aaa.txt .txt aaa
dirname基本语法
功能:返回完整路径后/的前面的部分,常用于返回路径部分
[root@localhost ~]# dirname /root/shelltest/aaa.txt /root/shelltest
自定义函数
[function] functionname [()]
{
Action;
[return int;]
}
调用直接写函数名 functionname [值]
实例:计算两个参数的和
#!/bin/bash function func_sum () { sum=$[$num1+$num2]; echo "sum is $sum" } read -p "请输入第一个数" num1 read -p "请输入第二个数" num2 func_sum $num1 $num2
shell编程综合案例
需求:
每天凌晨2点备份数据库admin 到/data/backup/db
备份开始和备份结束能够给出相应的提示信息
备份后的文件要求以备份时间为文件名,并打包成.tar.gz的形式
在备份的同时,检查10天前的备份数据库文件,如果有将其删除
#!/bin/bash
#完成数据库的定时备份
#备份的路径
BACKUP=/data/backup/db
#当前时间作为文件名
DATETIME=$(date +%Y_%m_%d_%H%M%S)
#echo $DATETIM
echo "=========开始备份========="
echo "备份路径 $BACKUP/$DATETIME.tar.gz"
#主机
HOST=localhost
#用户名
DB_USER=root
#密码
DB_PWD=root
#备份数据库名
DATABASE=test
#创建备份的路径
#如果备份的路径文件夹存在,就使用,否则就创建
[ ! -d "$BACKUP/$DATETIME" ] && mkdir -p "$BACKUP/$DATETIME"
#执行mysql备份数据库的指令
mysqldump -u{$DB_USER} -p{$DB_PWD} $DATABASE | gzip > $BACKUP/$DATETIME/$DATETIME.sql.gz
#打包备份文件
cd $BACKUP
tar -zcvf $DATETIME.tar.gz $DATETIME
#删除临时目录
rm -rf $BACKUP/$DATETIME
#删除十天前的文件
find $BACKUP -mtime +10 -name "*.tar.gz" -exec rm -rf {} \;
echo "=========备份成功========="
[root@izbp1603l3nn58lq8r0ekgz sbin]# crontab -e
#添加 10 2 * * * /usr/sbin/mysql_db_backup.sh
#保存退出
crontab: installing new crontab