shell编程

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

shell编程

shell 是一个命令行解释器他为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序用户可以用Shell 来启动、挂起、停止甚至是编写一些程序

shell 脚本的执行方式

脚本格式要求

  • 脚本以#!/bin/bash开头
  • 脚本需要有可执行权限
[ylq@rootylq shell]$ cat hello.sh
#!/bin/bash
echo "hello,world"

以脚本的绝对路径或相对路径执行shell

[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

用sh+脚本执行

[ylq@rootylq shell]$ sh hello.sh 
hello,world

shell的变量

  • Linux Shell 中的变量分为系统变量和用户自定义变量

系统变量

$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

  • 可通过set指令查看所有的系统变量
[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


shell 变量命名规范

  • 变量名称可以由字母、数字和下划线组成但不能以数字作为开头
  • 等号两侧不能由空格
  • 变量名称一般习惯为大写

将命令的返回值赋给变量

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 变量名=变量值 功能描述:将shell变量输出为环境变量/全局变量
  • source 配置文件 功能描述让修改后的配置信息立即生效
  • echo $变量名 功能描述查询环境变量的值

设置环境变量可以使得多个函数共享变量

#定义一个环境变量
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
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 脚本中使用

基本语法

  • $$ 当前进程的进程号
  • $! 后台运行的最后一个进程的进程好
  • $? 最后一次执行的命令返回状态如果这个变量的值为0。证明上一个命令正确如果这个变量的值非0则证明上一个命令执行不正确
#!/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 运算符

如何在shell中使用各自运算操作符

基本语法

$((运算式))或$[运算式]或expr m + n
  • expr 运算符之间要有空格如果需要将expr的结果赋给某个变量使用``
  • 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"

shell 条件判断

基本语法

[ condition ] 注意condition 前后都需要有空客

#非空返回true ,可使用$? 验证0为true>1为false

判断语句

  • = 字符串比较
  • 两个整数的比较
    • -lt 小于
    • -le 小于等于 little equal
    • -eq 等于
    • -gt 大于等于
    • -ne 不等于
  • 按照文件权限进行判断
    • -r 有读权限
    • -w 有写权限
    • -x 有执行权限
  • 按照文件类型进行判断
    • -f 文件存在并且是一个常规的文件
    • -e 文件存在
    • -d 文件存在并是一个目录
[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


shell 流程控制

if 单分支与多分支

单分支

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 语句

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


for循环

基本语法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 循环

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 读取控制台输入

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

返回完整路径/后的部分常用于获取文件名

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

功能返回完整路径最后/的前面部分常用于返回路径部分

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



shell 编程综合案例

备份数据库

  • 每天凌晨230备份数据库
  • 备份开始和结束能够给出提示
  • 备份文件要求以备份时间为文件名并打包成.tar.gz形式
  • 备份同时检查是否有10天前的备份数据库文件如果存在则删除
[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}成功-"


阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: shell