Linux--Shell编程入门

shell编程入门

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

脚本规范

  • 脚本格式要求

    1. 以#!/bin/bash 开头
    2. 脚本需要有可执行权限
  • 脚本的执行方式

    1. 输入脚本的绝对路径/相对路径

    这种方式要赋予脚本的x权限,再执行脚本

    shell 复制代码
    # 脚本内容如下
    #!/bin/bash
    echo "hello,world~~"
    # 具体执行如下
    ./hello.sh  或者 /root/shcode/hello.sh
    1. sh+脚本

    这种方式不需要x权限,直接执行即可。

sh 复制代码
sh hello.sh

变量

  • shell的变量

    1. shell的变量分为系统变量和用户自定义变量
    2. 系统变量有:HOME、PWD、SHELL、USER等
    3. 显示当前shell中所有变量:set
  • shell变量的定义

    1. 定义变量:变量名=值 (中间没有空格)
    shell 复制代码
    A=100
    echo $A  # 在输出的时候,要在变量前加$
    echo A=$A # 输出结果是A=100 ,A= 会输出位普通字符串
    1. 撤销变量:unset 变量
    shell 复制代码
    unset A
    1. 声明静态变量:readonly 变量,注意不能unset

      shell 复制代码
      readonly B=200
  • 定义变量的规则

    1. 变量名可以由字母、数字、下划线组成,但是不能以数字开头
    2. 等号两侧不能由空格
    3. 变量名称一般习惯大写
  • 将命令的返回值赋给变量

    shell 复制代码
    A=`date`  #反引号,运行里面的命令,将结果返回给A
    A=$(date)  # 等价于反引号

    设置环境变量

    shell 复制代码
    export 变量名=值  # 将设立了变量输出位环境变量/全局变量
    source 配置文件   # 让修改后的配置信息立即生效
    echo $变量名    # 查询环境变量的值

    shell脚本的多行注释

    shell 复制代码
    :<<!  #  这个必须单独一行
    注释内容
    !

    位置参数变量

    当执行一个shell脚本时,希望获取到命令行的参数信息,就可以使用位置参数变量,比如:

    shell 复制代码
    ./myshell.sh 100 200 # 这是一个执行shell的命令行,可以在myshell脚本中获取到参数信息

    基本语法:

    • n : n为数字,0代表命令本身,1-9代表第一到第九个参数。十以上的参数需要使用大括号,如$
    • \* : 代表命令行中的所有参数。* 把所有的参数看成一个整体
    • @:也代表命令行中的所有参数,不过@ 把每隔参数区分对待
    • $#: 代表命令行中的所有参数的个数

预定义变量

预定义变量就是shell设计者已经定义好的变量,可以直接在shell脚本中使用

基本语法:

sh 复制代码
$$ : 表示当前进程的进程号(PID)
$! : 后台运行的最后一个进程的进程号
$? :最后一次执行的命令的返回状态,如果这个变量的值为0,证明上一个命令正确执行;如果为非0(具体哪个数由命令自己决定),则证明上一个命令执行不正确。
举例:
#!/bin/bash
echo "当前执行的进程id=$$"
# 以后台方式运行一个脚本,并获取它的进程号
/root/shcode/myshell.sh &
echo "最后一个后台方式运行的进程id=$!"
echo "执行的结果是=$?"

运算符

基本语法:

shell 复制代码
"$((运算式))" 或 "$[运算式]"  或者 expr m + n
注意expr 运算符间要有空格,如果要将expr的结果赋给某个变量,需要使用``
expr m - n
expr \*,/,%   乘、除、取余
#举例
# 计算(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 "RES4=$RES4"

条件判断

shell 复制代码
# 基本语法
[ condition ]  # 注意condition前后要有空格
# 非空返回true,可使用$?验证(0为true,0>1为false)
[ someWords ]    //返回true
[ ]              // 返回false,中括号中间必须有空格
[ condition ] && echo ok || echo notok    # 条件满足,执行后面的语句
# 常用的判断条件
=  # 字符串比较 
# 两个整数的比较
-lt # 小于
-le # 小于等于 little equal
-eq # 等于
-gt # 大于
-ge # 大于等于
-ne # 不等于
# 按照文件权限进行判断
-r # 有读的权限
-w # 有写的权限
-x # 有执行的权限
# 按照文件类型进行判断
-f # 文件存在,并且是一个常规文件
-e # 文件存在
-d # 文件存在,并且是一个目录
# 应用实例
# "ok" 是否等于"ok"
if [ "ok" = "ok" ]
then
		echo "equal"
fi  # fi 表示if语句的结束
# 23 是否大于等于22
[ 23 -ge 22 ]
# /root/shcode/aa.txt 目录中的文件是否存在
[ -f /root/shcode/aa.txt ]

流程控制

shell 复制代码
# if 判断的基本语法
if [ 条件判断式 ]
then
  代码
fi
#  或者 多分支的形式
if [ 条件判断式 ]
then
  代码
elif  [ 条件判断式 ]
then
  代码
fi
# case 语句
case $变量名 in
"值1" )
如果变量的值等于值1,则执行这块的代码
;;
"值2" )
如果变量的值等于值2,则执行这块的代码
;;
* )
如果变量的值都不是以上的值,则执行这块的代码
;;
esac    # case 反写代表结束
# for循环 基本语法1
for 变量 in 值1 值2 值3...
do
程序
done
# for循环 基本语法2
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
# 案例1:打印命令行输入的参数 【这里可以看出$* 和 $@ 的区别】
# $* 是把输入的参数当成一个整体,所以只会输出一句话
for i in "$*"
do
	echon "num is $i"
done
# 使用 $@,会输出多次
for j in "$@"
do
	echon "num is $j"
done
# 案例2 从1加到100
SUM=0
for (( i=0;i<100;i++ ))
do
	SUM=$[$SUM+$i]
done
echo "总和sum=$SUM"
# while 循环
while [ 条件判断式 ]
do
程序
done

read读取控制台输入

shell 复制代码
read(选项)(参数)
常用选项有: -p :指定读取值时的提示符
		   -t :指定读取值时等待的时间(秒),如果没有在指定时间内输入,就不再等待了。
参数:指定读取值得变量名
# 案例1:读取控制台输入一个num 值
#!/bin/bash
read -p "请输入一个数NUM1=" NUM1
echo "你输入得值是$NUM1"
# 案例2:读取控制台输入一个num 值,在10秒内输入。
#!/bin/bash
read -t 10 -p "请输入一个数NUM2=" NUM2
echo "你输入得值是$NUM2"

函数

系统函数

shell 复制代码
basename   #返回完整路径最后/的部分,常用于获取文件名 
# basename命令会删掉所有的前缀包括最后一个'/'字符,然后将字符串显示出来。
basename [pathname] [suffix] 
# suffix为后缀,如果suffix被指定了,basename会将pathname中的suffix去掉。
# 案例:请返回/home/aaa/test.txt的"test.txt"部分
basename /home/aaa/test.txt  # 返回test.txt
basename /home/aaa/test.txt .txt  # 返回test
dirname # 返回完整路径最后/的前面的部分,常用于返回路径部分
dirname [文件绝对路径] # 从给定的绝对路径的文件名中去除文件名,返回剩下路径。
# 案例: 请返回/home/aaa/test.txt 的/home/aaa
dirname /home/aaa/test.txt

自定义函数

shell 复制代码
# 基本语法
[function] funname[()]
{
	Action;
	[return int;]
}
# 调用直接写函数名:funname [值]
# 案例: 计算输入两个参数的和,getSum
# 定义函数
fucntion getSum(){
	NUM=$[$n1+$n2]
	echo "总和是$NUM"
}
# 输入两个值
read -p "请输入第一个数" n1
read -p "请输入第二个数" n2
# 调用函数
getSum $n1 $n2

Shell编程的综合案例

  • 每天凌晨2:30备份数据库aliDB 到data/backup/db
  • 备份开始和备份结束能够给出相应的提示信息
  • 备份后的文件以备份时间为文件名,并打包成.tar.gz的形式,比如:2021-11-12_230101.tar.gz
  • 检查是否有10天前备份的数据库文件,如果有就将其删除。
shell 复制代码
#!/bin/bash
# 备份目录
BACKUP=/data/backup/db
# 当前时间
DATETIME=$(date +%Y-%m-%d_%H%M%S)
# 数据库地址
HOST=locahost
# 数据库用户名
DB_USER=root
# 数据库密码
DB_PWD=root
# 要备份的数据库名
DATABASE=aliDB
# 创建备份目录,如果不存在就创建目录
[ ! -d "${BACKUP}/${DATETIME}" ] && mkdir -p "${BACKUP}/${DATETIME}"
# 备份数据库
mysqldump -u${DB_USER} -p${DB_PWD} --host=${HOST} -q-R --datebases ${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}成功~"
sh 复制代码
# 设置定时任务
crontab -e 
30 2 * * * /usr/sbin/mysql_db_backup.sh
相关推荐
今天又在写代码18 小时前
操作系统v2
操作系统
wfsm1 天前
原码,反码,补码
操作系统
波特率1152002 天前
FreeRTOS当中的Mail Queue使用教程(CMSIS_v1)
单片机·操作系统·freertos
艾莉丝努力练剑3 天前
【Linux线程】Linux系统多线程(七):<线程同步与互斥>线程同步(下)
java·linux·运维·服务器·c++·学习·操作系统
NE_STOP4 天前
Linux实操--rpm与yum
操作系统
未来侦察班4 天前
从理想星环OS 看机器人网络进化路线(附下载链接)
网络·机器人·操作系统
NE_STOP5 天前
Linux实操--进程管理与服务管理
操作系统
星马梦缘5 天前
快表、页表地址获取+缓存、主存、硬盘数据获取
算法·操作系统·os·tlb
NE_STOP5 天前
Linux实操--磁盘分区挂载与网络配置
操作系统