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

  1. # vim hello.sh 创建脚本,一般通过 .sh 表示是一个可执行脚本文件
  2. # BEGIN 模拟打开 vim
  3. #!/bin/bash
  4. # 上述开头,表明使用 哪种 shell
  5. # 内容
  6. # END
  7. # 编写完成后
  8. # # 方式一:添加执行权限 x,执行脚本
  9. # # 方式二:使用 sh 脚本 直接执行
  10. # 单行注释
  11. :<<!
  12. !

一、Shell 变量

Linux Shell 变量分为,系统变量和用户自定义变量。

1. 系统变量

$HOME $PATH $SHELL $USER
使用 set 指令可以查看

  1. # 案例:环境变量 /etc/profile
  2. export 变量名=变量值
  3. export JAVA_HOME:$PATH
  4. source /etc/profile
  5. echo $JAVA_HOME

2. 自定义变量

  1. #!/bin/bash
  2. # 定义变量的语法 变量名=值,切记不要有空格
  3. # 销毁变量,unset 变量名
  4. # 静态变量,readonly变量名,注意无法 unset
  5. # 案例1:定义变量A
  6. A=100
  7. # 输出A,需要引用:$A 或 ${A}
  8. echo $A
  9. echo A=$A #不会被当作变量,原封输出
  10. echo "A=$A" #效果相同
  11. # 运行结果
  12. # 100
  13. # A=100
  14. # A=100
  15. # 案例2:撤销变量A
  16. unset A
  17. echo "A=$A"
  18. # 运行结果
  19. # A=
  20. # 案例3:声明静态B
  21. readonly B=2
  22. echo "B=$B"
  23. # 如果 unset B,运行时出错

说明:

  1. 变量名:字母,数字,下划线组成,但数字不可打头
  2. 等号两侧不能有空格
  3. 变量名习惯为大写
    1. # 4. `将反引号内容看作是命令,将结果返回给等号前的变量` 同理写法 $()
    2. A=`date`
    3. B=$(date)

    3. 位置参数变量

    当我们执行一个脚本的时候,希望获得命令中的参数值,使用位置参数变量 如:./myshell.sh 100 200,如何获取 100 200

  1. # 基本语法
  2. $n
  3. :<<!
  4. n 表示数字
  5. $0 代表命令本身
  6. $1-$9 表示 1-9 参数
  7. ${10} 表示 10 以上使用大括号
  8. !
  9. $*
  10. # 表示所有参数,将所有参数当作一个整体
  11. $@
  12. # 表示所有参数,将参数区分对待
  13. $#
  14. # 表示参数的个数

4. 预定义变量

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

  1. # 基本语法
  2. $$ # 当前进程的进程号 PID
  3. $! # 后台运行的最后一个进程的进程号 PID
  4. $? # 最后一次执行命令的返回状态,0表示成功,非0,不成功,具体根据指令
  5. # 案例
  6. #!bin/bash
  7. echo "当前执行的进程id=$$"
  8. # 以后台形式运行一个脚本,并获取进程号 &表示后台运行
  9. /root/shcode/myshell.sh &
  10. echo "最后一个后台方式运行的进程id=$!"
  11. echo "执行结果=$?"

二、运算符

  1. # 基本语法
  2. $((运算式)) 或者 $[运算式] 或者 expr 运算式
  3. # 说明1:如果使用 expr 的形式,
  4. # 运算符需要在两侧添加空格 expr m + n,若写成 m+n 结果是输出 m+n
  5. # 结果需要 `expr m + n` 来获取
  6. # 乘法 \*,除法 /,取余 %

三、条件判断

if

基本格式:

  1. # 基本语法
  2. # 说明,条件condition 前后有空格
  3. [ condition ]
  4. # 非空返回 true,可使用 $? 验证,0为 ture,>1 为 false
  5. # [ ] 中间只有一个空格的含义就是为空
  6. [ condition ] && echo OK || echo notOK //条件满足,执行后面的语句
  7. # 常用的判断语句
  8. 1) = 字符串比较
  9. 2) 整数比较
  10. -lt 小于<
  11. -le 小于等于<=
  12. -eq 等于 ==
  13. -gt 大于 >
  14. -ge 大于等于 >=
  15. -ne 不等于 !=
  16. 3) 按照文件的权限 取反!
  17. -r 有读
  18. -w 有写
  19. -x 有执行
  20. 4) 按照文件类型 取反!
  21. -f 文件存在,且普通文件
  22. -e 文件存在
  23. -d 文件存在,且是目录
  24. ### 案例:
  25. ## 1."ok" 是否等于 "ok"
  26. if [ "ok" = "ok" ]
  27. then
  28. echo "equal"
  29. fi
  30. ## 2.23 是否大于等于22
  31. if [ 23 -ge 22 ]
  32. then
  33. echo "大于"
  34. fi
  35. ## 3.文件是否存在 /root/school/data.txt
  36. if [ -f /root/school/data.txt ]
  37. then
  38. echo "存在"
  39. fi

多分支:

  1. # 单分支
  2. if [ condition ]
  3. then
  4. 代码逻辑
  5. fi
  6. # 多分支
  7. if [ condition ]
  8. then
  9. 代码逻辑
  10. elif [ condition ]
  11. then
  12. 代码逻辑
  13. fi

case

  1. case $变量名 in
  2. "值1")
  3. 代码逻辑
  4. ;;
  5. "值2")
  6. 代码逻辑
  7. ;;
  8. *)
  9. default 代码逻辑
  10. ;;
  11. esac

for

  1. # 基础语法
  2. # 1. 比如 in "$*"/in "$@"
  3. for 变量 in 1 2 3 ...
  4. do
  5. 程序
  6. done
  7. # 2. 有步长
  8. for((初始值;循环条件;变量变化))
  9. do
  10. 程序
  11. done
  12. # 案例 从1加到100,显示最后结果
  13. #!/bin/bash
  14. SUM=0
  15. for((i=1;i<=100;i++))
  16. do
  17. SUM=$[$SUM+$i]
  18. done
  19. echo "SUM=$SUM"

while

  1. while [ condition ]
  2. do
  3. 程序
  4. done

read

  1. # 动态读取控制台输入
  2. read [option](参数)
  3. option
  4. -p:指定提示符
  5. -t:等待时间,如果超过就不等了
  6. 参数:
  7. 变量:指定读取值的变量名
  8. #!/bin/bash
  9. read -p "请输入数字" NUM1
  10. echo "输入信息为$NUM1"
  11. read -t 100 -p "请输入数字" NUM2
  12. echo "结果$NUM2"

函数

也是可以分为 系统函数,自定义函数

系统函数

  1. # 举例 basename 用于返回完整路径最后 / 后的内容,不包括 / ,如果有后缀,也把后缀删除了
  2. basename [pathname] [suffix(option)]
  3. # 举例 dirname 用于返回完整路径最后 / 前的内容,不包括 /
  4. dirname /home/aa/ccc/dd.txt

自定义函数

  1. # 函数的定义
  2. [ function ] functionName[()]
  3. {
  4. Action;
  5. [return int;]
  6. }
  7. # 函数的调用
  8. functionName [值]
  9. # 案例 计算两个参数和,动态获取
  10. #!/bin/bash
  11. # 声明
  12. funciton getSum(){
  13. SUM=$[$n1+$n2]
  14. echo "sum=$SUM"
  15. }
  16. read -p "输入加数1:" n1
  17. read -p "输入加数2:" n2
  18. # 使用
  19. getSum $n1 $n2

综合案例

需求分析:

  1. 脚本放在 /usr/sbin 下,取名 mysql_db_backup.sh
  2. 每天凌晨2:30备份数据库hspedu到/data/backup/db
  3. 备份开始和备份结束能够给出相应的提示信息
  4. 备份后的文件要求以备份时间为文件名,并打包成.tar.gz的形式,比如:2021-03-12_230201.tar.gz
  5. 在备份的同时,检查是否有10天前备份的数据库文件,如果有就将其删除。
  1. vim /usr/sbin/mysql_db_backup.sh
  2. #!/bin/bash
  3. # 1.备份目录
  4. BACKUP=/data/backup/db
  5. # 2.获取当前系统时间
  6. DATETIE=$(date +%Y-%m-%d_%H%M%S)
  7. # 3.数据库信息
  8. ## 数据库地址
  9. DB_HOST=localhost
  10. ## 数据库用户名
  11. DB_USER=root
  12. ## 数据库密码
  13. DB_PW=root
  14. ## 需要备份的数据库
  15. DATABASE=csz
  16. # 4.创建备份目录
  17. [ ! -d "${BACKUP}/${DATETIME}" ] $$ mkdir -p "${BACKUP}/${DATETIME}"
  18. # 5.备份数据库
  19. mysqldump -u${DB_USER} -p${DB_PW} --host=${DB_HOST} -q -R --databases=${DATABASE} | gzip > ${BACKUP}/${DATETIME}/$DATETIME.sql.gz
  20. # 6.打成 tar 包,再删除 sql.gz 文件
  21. cd ${BACKUP}
  22. tar -zcvf $DATETIE.tar.gz ${DATETIE}
  23. rm -rf ${BACKUP}/${DATETIE}
  24. # 7.删除10前的备份文件,如果有
  25. find ${BACKUP} -atime +10 -name "*.tar.gz" -exec rm -rf {} \;
  26. echo "数据库配备结束${DATEBASE}"
  27. ## 创建定时任务
  28. crontab -e
  29. 30 2 * * * /usr/sbin/mysql_db_backup.sh