shell 是一个命令行解释器,他为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell 来启动、挂起、停止甚至是编写一些程序
脚本格式要求:
[ylq@rootylq shell]$ cat hello.sh
#!/bin/bash
echo "hello,world"
[ylq@rootylq shell]$ vim hello.sh
[ylq@rootylq shell]$ ./hello.sh
-bash: ./hello.sh: Permission denied
[ylq@rootylq shell]$ ll
total 4
-rw-rw-r-- 1 ylq ylq 31 Jan 18 10:59 hello.sh
[ylq@rootylq shell]$ chmod u+x hello.sh
[ylq@rootylq shell]$ ./hello.sh
hello,world
[ylq@rootylq shell]$ sh hello.sh
hello,world
$HOME, $PWD ,$SHELL, $USER等
[ylq@rootylq shell]$ echo $HOME
/home/ylq
[ylq@rootylq shell]$ echo $home
[ylq@rootylq shell]$ echo $PWD
/home/ylq/shell
[ylq@rootylq shell]$ echo $USER
ylq
[ylq@rootylq shell]$ set |more
定义变量
变量名=值
撤销变量
unset 变量
声明静态变量
readonly 变量,注意不能unset
#!/bin/bash
#定义变量
A=100
#输出变量需要加上$
echo A=$A
echo "A=$A"
#撤销变量A
unset A
echo A=$A
#声明静态变量,不能unset
readonly B=2
echo "B=$B"
unset B
[ylq@rootylq shell]$ ./var.sh
A=100
A=100
A=
B=2
./var.sh: line 16: unset: B: cannot unset: readonly variable
A=`date`
A=$(date)
C=`date`
echo C=$C
D=$(date)
echo D=$D
[ylq@rootylq shell]$ ./var.sh
A=100
A=100
A=
B=2
C=Wed Jan 18 11:26:38 CST 2023
D=Wed Jan 18 11:26:38 CST 2023
基本语法
设置环境变量,可以使得多个函数共享变量
#定义一个环境变量
export YLQPATH=/home/ylq
[root@rootylq ~]# vim /etc/profile
[root@rootylq ~]# exco $YLQPATH
-bash: exco: command not found
[root@rootylq ~]# echo $YLQPATH
[root@rootylq ~]# source /etc/profile
[root@rootylq ~]# echo $YLQPATH
/home/ylq
shell 脚本的多行注释
:<<!
注释内容
!
当执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量
基本语法
n代表数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数需要用大括号表示,如${10}
#!/bin/bash
echo "$0 1=$! 2= $2"
echo "所有参数=$*"
echo “$@”
echo "参数个数=$#"
[root@rootylq shell]# chmod u+x myshell.sh
[root@rootylq shell]# ./myshell.sh 100 200
./myshell.sh 1= 2= 200
所有参数=100 200
“100 200”
参数个数=2
[root@rootylq shell]#
就是shell 设计者事先已经定义好的变量,可以直接在shell 脚本中使用
基本语法:
#!/bin/bash
echo "当前执行的进程id=$$"
#以后台方式运行一个脚本,并获取他的进程号
/home/ylq/shell/myshell.sh &
echo "最后一个后台方式运行的子进程i=$!"
echo “执行结果是=$?”
[root@rootylq shell]# chmod u+x preVAr.sh
[root@rootylq shell]# ./pre
-bash: ./pre: No such file or directory
[root@rootylq shell]# ./preVAr.sh
当前执行的进程id=18024
最后一个后台方式运行的子进程i=18025
“执行结果是=0”
[root@rootylq shell]# /home/ylq/shell/myshell.sh 1= 2=
所有参数=
“”
参数个数=0
^C
如何在shell中使用各自运算操作符
基本语法
$((运算式))或$[运算式]或expr m + n
expr \*,/,% 乘,除,取余
[root@rootylq shell]# ./oper.sh 30 40
RES1=20
RES2=20
RES3=20
SUM=70
[root@rootylq shell]# cat oper.sh
#!/bin/bash
#计算(2+3)*4 的值
#使用第一种方法
RES1=$(((2+3)*4))
echo "RES1=$RES1"
#使用第二种方式
RES2=$[(2+3)*4]
echo "RES2=$RES2"
#使用第三种方式 expr
TEMP=`expr 2 + 3`
RES3=`expr $TEMP \* 4`
echo "RES3=$RES3"
SUM=$[$1+$2]
echo "SUM=$SUM"
基本语法
[ condition ] 注意condition 前后都需要有空客
#非空返回true ,可使用$? 验证(0为true,>1为false)
判断语句
[root@rootylq shell]# ./ifdemo.sh
equal
23大于22
文件存在
[root@rootylq shell]# cat ifdemo.sh
#!/bin/bash
#判断字符串是否相同
if [ "ok" = "ok" ]
then
echo "equal"
fi
#判断23是否发育22
if [ 23 -ge 22 ]
then
echo "23大于22"
fi
#判断文件目录中文件是否存在
if [ -f /home/ylq/shell/myshell.sh ]
then
echo "文件存在"
fi
if [ ]
then
echo "看我存在不"
fi
单分支
if [ ]
then
echo "看我存在不"
fi
多分支
[root@rootylq shell]# chmod u+x ifcase.sh
[root@rootylq shell]# ./ifcase.sh 70
及格了,哥们
[root@rootylq shell]# ./ifcase.sh 59
不及格,回家有你好果子吃
[root@rootylq shell]# cat ifcase.sh
#!/bin/bash
if [ $1 -ge 60 ]
then
echo "及格了,哥们"
elif [ $1 -lt 60 ]
then
echo "不及格,回家有你好果子吃"
fi
[ 条件判断式 ],中括号和条件判断式之间必须要有空格
case $变量名 in
“值1”)
程序1
;;
“值2”
程序2
;;
…
esac
[root@rootylq shell]# chmod u+x casedemo.sh
[root@rootylq shell]# ./casedemo.sh 1
Monday
[root@rootylq shell]# ./casedemo.sh 2
Tuesday
[root@rootylq shell]# ./casedemo.sh 3
Wednesay
[root@rootylq shell]# ./casedemo.sh 4
Other...
[root@rootylq shell]# cat casedemo.sh
#!/bin/bash
case $1 in
"1")
echo "Monday"
;;
"2")
echo "Tuesday"
;;
"3")
echo "Wednesay"
;;
*)
echo "Other..."
;;
esac
基本语法1:
for 变量 in 值1 值2 …
do
程序
done
基本语法2
for ((初始值;循环控制条件;变量变化))
do
程序
done
[root@rootylq shell]# ./fordemo.sh 100 200 300
测试*
num is 100 200 300
*******************************
测试@
num@ is 100
num@ is 200
num@ is 300
./fordemo.sh: line 21: echo*********************************************: command not found
测试基本语法,打印1~10
SUM=1
SUM=3
SUM=6
SUM=10
SUM=15
SUM=21
SUM=28
SUM=36
SUM=45
SUM=55
[root@rootylq shell]# cat fordemo.sh
#!/bin/bash
#$*将输入的参数当作一个整体,所以只会输出一句话
echo "测试*"
for i in "$*"
do
echo "num is $i"
done
#$@ 将输入的参数分别对待,有几个参数九江输出几句话
echo "*******************************"
echo "测试@"
for i in "$@"
do
echo "num@ is $i"
done
echo"*********************************************"
echo "测试基本语法,打印1~10"
SUM=0
for(( i=1; i<=10; i++))
do
SUM=$[ $SUM+$i ]
echo "SUM=$SUM"
done
while [ 条件判断式 ]
do
程序
done
[root@rootylq shell]# ./whiledemo.sh 100
执行结果=5050
[root@rootylq shell]# ./whiledemo.sh 10
执行结果=55
[root@rootylq shell]# cat whiledemo.sh
#!/bin/bash
SUM=0
i=0
while [ $i -le $1 ]
do
SUM=$[ $SUM+$i ]
#i自增
i=$[ $i+1 ]
done
echo "执行结果=$SUM"
read(选项)(参数)
选项:
-p: 指定读取值时的提示符
-t: 指定读取值时的等待时间(秒),如果没有在指定的时间内输入,就不再等待了
参数:
[root@rootylq shell]# vim readdemo.sh
[root@rootylq shell]# ./readdemo.sh
请输入一个数NUM1=10
输入的值是:10
请在10秒内输入一个数NUM2= 20
输入的值是NUM2=20
[root@rootylq shell]# ./readdemo.sh
请输入一个数NUM1=10
输入的值是:10
请在10秒内输入一个数NUM2= 输入的值是NUM2=
[root@rootylq shell]# cat readdemo.sh
#!/bin/bash
read -p "请输入一个数NUM1=" NUM1
echo "输入的值是:$NUM1"
read -t 10 -p "请在10秒内输入一个数NUM2= " NUM2
echo "输入的值是NUM2=$NUM2"
shell函数可以有自定义函数,也可以有系统函数
返回完整路径/后的部分,常用于获取文件名
basename[ pathname ] [ suffix ]
basename 命令会删掉所有的后缀包括最后一个/字符,将字符串显示出来
suffix为后缀,如果suffix被制定了,basename会将pathname或string 的suffix去掉
[root@rootylq shell]# clear
[root@rootylq shell]# basename /home/ylq/shell/myshell.sh
myshell.sh
[root@rootylq shell]# basename /home/ylq/shell/myshell.sh .txt
myshell.sh
[root@rootylq shell]#
功能:返回完整路径最后/的前面部分,常用于返回路径部分
dirname 文件绝对路径
功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录部分)
[root@rootylq shell]# dirname /home/ylq/shell/myshell.sh
/home/ylq/shell
[root@rootylq shell]#
[ function ] funname [()]
{
Action;
[return int;]
}
调用直接写函数名: funname [值]
[root@rootylq shell]# ./functiondemo.sh
请输入n1=10
情输入n2=20
SUM is 30
[root@rootylq shell]# cat functiondemo.sh
#!/bin/bash
#定义函数 getSum
function getSum(){
SUM=$[ $n1+$n2 ]
echo "SUM is $SUM"
}
#输入两个值
read -p "请输入n1=" n1
read -p "情输入n2=" n2
#调用自定义函数
getSum $n1 $n2
备份数据库:
[root@rootylq ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@rootylq ~]# crontab -l
30 2 * * * /usr/sbin/mysql_db_backup.sh
#!/bin/bash
#备份目录
BACKUP=/data/backup/db
#获取当前时间
DATETIME=$(date +%Y-%m-%d_%H%M%S)
echo $DATETIME
#数据库地址
HOST=localhost
#数据库用户名
DB_USER=root
DB_PW=Ylq1368670840!
#要备份的数据库
DATABASE=aliyun
#创建备份目录,如果不存在则创建
[ ! -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}成功-"