如果对你有帮助,就点个赞吧~
本文主要介绍Shell从执行到编写、以及定时执行shell脚本的相关内容
1. Shell Basis
- Linux的命令解释器
- 用于解释用户对操作系统的操作
- 比如ls命令即为shell所接收分析与执行
- Ubuntu和CentOS 7默认使用的shell为Bash
2. Linux启动过程(六步)
- BIOS引导
- MBR - 主引导记录
- BootLoader(grub) - 启动和引导内核的主要工具
- kernel
- systemd - 1号进程
- 系统初始化 - shell脚本
3. 编写shell脚本
- UNIX哲学: 一条命令只做一件事
- 脚本文件: 组合命令和多次执行
- 赋予文件执行权限 - chmod u+x file_name
- 文件首行添加声明 #! /bin/bash
- 如果是bash file_name.sh - 则首行视为注释
- 如果是./file_name.sh则用系统默认的shell执行, 读取首行后改用bash
4. shell脚本的执行方式及影响
- bash ./file_name.sh
- 不需要可执行权限
- 产生新的子进程 - 不会影响当前运行环境
- ./file_name.sh - Sha-Bang解释命令
- source ./file_name.sh
- . file_name - source ./file_name.sh的另一种写法
- 内建命令不需要创建子进程
- 内建命令对当前shell生效
5. 管道
-
管道
-
管道符
- 匿名管道
- Shell编程经常用到的通信工具
- 「|」, 将前一个命令的执行结果传递给后面的命令
- ll | more
- tail -f CRON.log* | grep “RuntimeError” -C 10
- ps -ef | grep python
- cat file_name | wc -l
-
子进程与子Shell
6. 重定向
- 一个进程会默认打开标准输入、标准输出、错误输出三个文件描述符
- 输入重定向符号
- 输出重定向符号
- “>” - 清空并写入
- “>>” - 追加
- “2>” - 错误写入
- “&>” - 正确和错误都写入
- 输入输出重定向组合使用
- cat > output_file_name << EOF
7. 变量
- 定义变量
- 变量赋值
- shell变量不区分类型 - 弱类型
- 赋值时等号两侧不允许出现空格,因为空格会让shell认为前面不是变量名而是命令
- 变量名=变量值
- 使用let为变量赋值
- 将命令赋值给变量
- 将命令结果赋值给变量, 使用$()或者``
- let c=$(ls -l /etc)
- let c=
ls -l /etc
- 变量值有空格或特殊字符时可以包含在""或’'中
- test_string=“Hello Bash”
- test_string=‘Hello “Bash”’
- 变量引用
- ${变量名}
- echo ${变量名}查看变量的值
- ${变量名}在部分情况下可以省略为 $变量名 - 不引起歧义
- 变量的作用范围
- 默认作用范围 - 只针对当前的终端/Shell, 在其父进程或子进程等都不生效
- 希望生效时改变执行方式 - source命令执行
- 希望子进程得到父进程的变量 - export关键字
- 变量名=变量值;export 变量名
- export 变量名=变量值
- 系统环境变量
- 环境变量 - 每个Shell打开都可以获得的变量
- set和env命令
- env | more 查看变量
- echo $环境变量名 - echo$PATH
- $PATH
- 命令的搜索路径
- PATH=$PATH:new_path_1:new_path_2
- $PS1 - 当前提示的终端
- $?$$$0
- 上一条命令是否执行成功
- 显示当前进程的PID
- 显示当前进程的名称
- 位置变量 - $1 $2… $9 ${10}…
- 规避读入的值是空值 - echo ${2-_} - 参数替换
8. 环境变量配置文件 - 4个文件1个目录
- /etc/profile
- /etc/profile.d/
- ~/.bash_profile
- ~/.bashrc
- /etc/bashrc
- 让配置文件的修改生效
- 退出重开
- source modified_config_file_path
9. 数组
- 定义数组
- IPTS=( 10.0.0.1 10.0.0.2 10.0.0.3 )
- 显示数组的所有元素
- 显示数组元素个数
- 显示数组的第一个元素
- echo ${IPTS}
- echo $IPTS
- echo ${IPTS[0]}
10. 转义与引用
- 特殊字符
- 不仅有字面意义,还有元意(meta-meaning)
- # 注释
- ; 分号, 分隔命令
- \ 转义符号
- " 引用
- ’ 引用
- 转义
- 单个字符前的转义符号
- 单个字母的转义 - \n \r \t
- 单个非字母的转义 - \$ \" \\
- 引用
- " 双引号 - 不完全引用
- ’ 单引号 - 完全引用
- ` 反引号 - 引用命令结果
11. 运算符
- 赋值运算符
- 算数运算符
- 数字常量
- 双圆括号 - let命令的简化
12. 特殊字符大全
13. 测试与判断
- 退出与退出状态
- exit - 会返回出错编码
- exit 10 - 自定义返回,会返回10给Shell, 返回值非0为不正常退出
- $? 判断当前Shell前一个进程是否正常退出
- 测试命令test
- 文件测试
- 整数比较测试
- 字符串测试
- test测试语句可以简化为[[]]形式
- 根据$?判断
14. 条件判断
- if [测试条件成立] 或者命令的返回值为0
- then
- elif [测试条件成立] 或者命令的返回值为0
- then
- else
- fi - 结束判断
15. 嵌套的if
- if [条件测试成立] - 如:判断用户
- then 执行操作
- if [测试条件成立] - 如:判断是否有可执行权限
- then 执行操作
- fi
- fi
16. case 分支
- case “$1” in
- “start”|“START”)
- “stop”|“STOP”)
- “restart”|“reload”)
- *)
- echo “Usage: $0 {start|stop|restart|reload}”
- ;;
- esac
17. 循环
-
for循环的语法
- for 参数 in 列表
- do 执行的命令
- done - 封闭一个循环
-
列表包含多个变量,变量用空格分隔
-
对文本处理,要使用文本查看命令取出文本内容后处理
-
批量重命名示例
- for filename in
ls *.mp3
- do
- mv $filename $(basename $filename .mp3).mp4
- done
-
while循环
-
until循环
-
循环输出计数
- while [ $a -lt 10 ]
- do
- done
-
死循环 - 构建交互式菜单
18. C语言风格的for
-
for((变量初始化;循环判断条件;变量变化))
-
do
-
done
-
循环输出计数
- for ((i=1; i<=10; i++))
- do
- done
19. 嵌套循环和break, continue
- 循环可以嵌套循环
- 循环和条件判断可以相互嵌套
- break,continue可以退出循环
- 示例
- for script_name in /etc/profile.d/*.sh
- do
- if [-x $script_name] ; then
- fi
- done
20. 使用循环处理命令行参数
- 命令行参数可以使用$1 $2…${10}… $n进行读取
- $0表示脚本名称
- $*和$@表示所有位置参数
- $#代表位置参数的数量
- 示例
- for pos in $*:
- do
- if [ “$pos” = “help” ]; then
- done
- while [ $# -gt 1 ]
- do
- if [ “$1” = “help” ]; then
- fi
- shift
- done
21. 自定义函数
-
函数定义
-
函数执行
-
示例
- function cdls() {
- cd /var
- ls
- }
-
函数作用范围的变量
-
函数的参数
-
指定文件夹
- function cdls() {
- cd $1
- ls
- }
-
检查进程号对应的进程是否存活
- checkpid(){
- local i
- for i in $* ; do
- [ -d “/proc/$i” ] && return 0
- done
- return 1
- }
22. 系统函数库
- 可在脚本中引用系统自建的函数库
- /etc/init.d/functions
- source /etc/init.d/functions 导入系统函数
- 自建函数库
23. 脚本资源控制
- 脚本优先级控制
- nice和renice调整脚本优先级,控制对cpu占用
- 避免出现不可控的死循环
- ulimit -a 查看普通用户的系统限制(root不受限制)
24. 信号
- 捕获信号
- kill默认会发送15号信号给应用程序
- ctrl+c发送2号信号给应用程序
- 9号信号不可阻塞
- 捕获信号的编写
- trap命令捕获信号
- 死循环测试信号捕获 - 满负载运行,禁止在服务器上测试
- trap “echo sig 15” 15
- trap “echo sig 2” 15
- echo $$
- while :
- do
- done
25. 一次性计划任务
- 计划任务: 让计算机在指定实践运行程序
- at命令设置一次性任务
- at命令查询没有执行的一次性任务
26. 周期性计划任务
- cron
- 配置方式
- 查看现有的计划任务
- 配置格式
- 分钟 小时 日期 月份 星期 执行
- 注意命令的路径问题
- 示例
- * * * * * date >> /temp/date.txt
- 无论哪个月哪个星期的哪个小时的哪一分钟,都追加date返回值到date.txt - 即每分钟执行一次
- * * * * 1,5 date >> /temp/date.txt
- * * * * 1-5 date >> /temp/date.txt
- 星期一到星期五都执行
- 7月7日的时候如果是星期一到星期五的话,每分钟执行
- 0 9 * * * 1 date >> /temp/date.txt
27. 脚本加锁
- 如果计算机不能按照预期时间进行
- anacontab 延时计划任务
- /etc/cron.d/0hourly
- /etc/anacrontab
- /etc/cron.daily/logrotate
- flock锁文件
- flock -xn “/tmp/f.lock” -c “/root/a.sh” # 排他锁,同时只能运行一个
- 上一个脚本没有结束前, 再次运行该脚本会自动结束, 无法运行.
好课推荐: Linux实战技能100讲🔥