目录
1. 使用while read line和/etc/passwd,计算用户id总和。
2. 总结索引数组和关联数组,字符串处理,高级变量使用及示例。
12. 通过mkfifo, cat, 来解释秒杀的并发问题,如何通过队列解决的?最好结合图形。说明消息队列的作用?
13. 总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。
16. 手写chkconfig服务脚本,可以实现服务的开始,停止,重启。
22. 总结对称加密和非对称加密算法和用openssl签发证书步骤
1. 使用while read line和/etc/passwd,计算用户id总和。
[root@rocky8 /data]$ bash userid.sh
86721
[root@rocky8 /data]$ cat userid.sh
#! /bin/bashsum=0
while read line;do
userid=`echo $line | cut -d":" -f3`;
let sum+=userid
done < /etc/passwdecho $sum
2. 总结索引数组和关联数组,字符串处理,高级变量使用及示例。
2.1 索引数组
- 存储一系列有序的元素,每个元素通过索引(通常是整数)访问。
- 数组的索引从0开始
- 普通数组可以不事先声明,直接使用
例:
[root@rocky8 /data]$ colors=("black" "green" "red")
[root@rocky8 /data]$ echo $colors
black
[root@rocky8 /data]$ echo ${colors[2]}
red
[root@rocky8 /data]$ echo ${colors[1]}
green
2.2 关联数组
- 存储一系列元素,可以自定义下标
- 关联数组必须事先声明,才可以使用; declare -A xxx
例:
[root@rocky8 /data]$ declare -A cats
[root@rocky8 /data]$ cats[boss]=langge
[root@rocky8 /data]$ cats[staff]=naicha
[root@rocky8 /data]$ echo ${cats[boss]}
langge
[root@rocky8 /data]$ echo ${cats[staff]}
naicha
2.3 字符串处理
2.3.1字符串切片
基于偏移量取字符串
# 返回字符串变量 var 的字符的长度 , 一个汉字算一个字符${#var}# 返回字符串变量 var 中从第 offset 个字符后(不包括第 offset 个字符)的字符开始,到最后的部分,offset 的取值在 0 到 ${#var}-1 之间 (bash4.2 后,允许为负值 )${var:offset}# 返回字符串变量 var 中从第 offset 个字符后(不包括第 offset 个字符)的字符开始,长度为 number 的部分${var:offset:number}# 取字符串的最右侧几个字符 , 取字符串的最右侧几个字符 , 注意:冒号后必须有一空白字符${var: -length}# 从最左侧跳过 offset 字符,一直向右取到距离最右侧 lengh 个字符之前的内容 , 即 : 掐头去尾${var:offset:-length}# 先从最右侧向左取到 length 个字符开始,再向右取到距离最右侧 offset 个字符之间的内容 , 注意: -length前空格 , 并且 length 必须大于 offset${var: -length:-offset}
[root@rocky8 /data]$ var=abcd1235[root@rocky8 /data]$ echo ${#var}
8
跳过前3个字符,取后面的字符:
[root@rocky8 /data]$ echo ${var:3}
d1235
跳过前2个字符,取后面3个字符:
[root@rocky8 /data]$ echo ${var:2:3}
cd1
掐头去尾
[root@rocky8 /data]$ echo ${var:4:-3}
1
基于模式取字符串
# 其中 word 可以是指定的任意字符 , 自左而右,查找 var 变量所存储的字符串中,第一次出现的 word, 删除字符串开头至第一次出现 word 字符串(含)之间的所有字符 , 即懒惰模式 , 以第一个 word 为界删左留右${var#*word}# 从 var 变量的值中删除以 word 开头的部分${var#word}# 同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由 word 指定的字符之间的所有内容 , 即贪婪模式 , 以最后一个 word 为界删左留右${var##*word}${var##word}
[root@rocky8 /data]$ net12="/etc/sysconfig/network-scripts"[root@rocky8 /data]$ echo ${net12#*etc}/sysconfig/network-scripts/
[root@rocky8 /data]$ echo ${net12##*/}
network-scripts
# 其中 word 可以是指定的任意字符 , 功能:自右而左,查找 var 变量所存储的字符串中,第一次出现的 word,删除字符串最后一个字符向左至第一次出现 word 字符串(含)之间的所有字符 , 即懒惰模式 , 以从右向左的第一个 word 为界删右留左${var%word*}${var%word}# 同上,只不过删除字符串最右侧的字符向左至最后一次出现 word 字符之间的所有字符 , 即贪婪模式 , 以从右向左的最后一个 word 为界删右留左${var%%word*}
[root@rocky8 /data]$ net12="/etc/sysconfig/network-scripts"[root@rocky8 /data]$ echo ${net12%etc*}
/
[root@rocky8 /data]$ echo ${net12%%c*}
/et
2.3.2 查找替换
# 查找 var 所表示的字符串中,第一次被 pattern 所匹配到的字符串,以 substr 替换之,懒惰模式${var/pattern/substr}# 查找 var 所表示的字符串中,所有能被 pattern 所匹配到的字符串,以 substr 替换之,贪婪模式${var//pattern/substr}# 查找 var 所表示的字符串中,行首被 pattern 所匹配到的字符串,以 substr 替换之${var/#pattern/substr}# 查找 var 所表示的字符串中,行尾被 pattern 所匹配到的字符串,以 substr 替换之${var/%pattern/substr}
[root@rocky8 /data]$ var=abcd1235[root@rocky8 /data]$ echo ${var/1235/1234}
abcd1234
2.3.3 查找删除
# 删除 var 表示的字符串中第一次被 pattern 匹配到的字符串,懒惰模式${var/pattern}# 删除 var 表示的字符串中所有被 pattern 匹配到的字符串,贪婪模式${var//pattern}# 删除 var 表示的字符串中所有以 pattern 为行首匹配到的字符串${var/#pattern}# 删除 var 所表示的字符串中所有以 pattern 为行尾所匹配到的字符串${var/%pattern}
[root@rocky8 /data]$ var=abcd1234[root@rocky8 /data]$ echo ${var/12}
abcd34
2.3.4 字符大小写切换
# 把 var 中的所有小写字母转换为大写${var^^}# 把 var 中的所有大写字母转换为小写${var,,}
[root@rocky8 /data]$ var=abcd1234[root@rocky8 /data]$ echo ${var^^}
ABCD1234
2.3.5 变量拓展
# 扩展以所有 prefix 开头的变量${!prefix*}${!prefix@}
[root@rocky8 /data]$ echo ${!file*}
file1 file2 file3
2.3.6 高级变量用法
高级变量赋值
![](https://i-blog.csdnimg.cn/blog_migrate/761de56c781827c8551a7b7a5d473481.png)
例:
[root@rocky8 /data]$ studentid=013
[root@rocky8 /data]$ student=${studentid-huang}
[root@rocky8 /data]$ echo $student
013
[root@rocky8 /data]$ studentid=
[root@rocky8 /data]$ echo $student[root@rocky8 /data]$ unset studentid[root@rocky8 /data]$ student=${studentid-huang}
[root@rocky8 /data]$ echo $student
huang
有类型变量
declare [ 选项 ] 变量名选项:-r 声明或显示只读变量-i 将变量定义为整型数-a 将变量定义为数组-A 将变量定义为关联数组-f 显示已定义的所有函数名及其内容-F 仅显示已定义的所有函数名-x 声明或显示环境变量和函数 , 相当于 export-l 声明变量为小写字母 declare -l var = UPPER-u 声明变量为大写字母 declare -u var = lower-n make NAME a reference to the variable named by its value
变量间接引用
eval命令
eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量,该命令对变量进行两次扫描
例:
[root@rocky8 /data]$ n=5
[root@rocky8 /data]$ echo {1..$n}
{1..5}
[root@rocky8 /data]$ eval echo {1..$n}
1 2 3 4 5
间接变量引用
# 方法 1# 变量赋值eval tempvar = \$ $variable1# 显示值eval echo \$ $variable1eval echo '$' $variable1# 方法 2# 变量赋值tempvar = ${!variable1}# 显示值echo ${!variable1}
[root@rocky8 /data]$ n1=n2
[root@rocky8 /data]$ n2=huang
[root@rocky8 /data]$ eval name=${!n1}
[root@rocky8 /data]$ echo $name
huang
3. 求10个随机数的最大值与最小值。
[root@rocky8 /data]$ bash max.sh
All number are 8734 25386 2809 31991 22394 10396 17160 24796 3799 23887
max is 31991
min is 2809[root@rocky8 /data]$ cat max.sh
#! /bin/bashdeclare -i min max
declare -a numsfor ((i=0;i<10;i++));do
nums[$i]=$RANDOM
[ $i -eq 0 ] && min=${nums[0]} && max=${nums[0]} && continue
[ ${nums[$i]} -gt $max ] && max=${nums[$i]} && continue
[ ${nums[$i]} -lt $min ] && min=${nums[$i]}
done
echo "All number are ${nums[*]}"
echo max is $max
echo min is $min
4. 使用递归调用,完成阶乘算法实现。
[root@rocky8 /data]$ bash fact.sh 10
3628800
[root@rocky8 /data]$ cat fact.sh
#!/bin/bash
fact() {
if [ $1 -eq 1 ];then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}fact $1
5. 解析进程和线程的区别?
- 进程是操作系统分配资源的最小单位,线程是程序执行的CPU调用的最小单位
- 一个进程由多个线程组成,最少有一个线程,线程是进程中的不同执行路线
- 进程之间相互独立,但同一进程内的各个线程共享程序的内存空间和资源
6. 解析进程的结构。
进程的结构主要包括以下几个部分:
- 程序代码:用来存放可执行文件的操作指令,就是可执行程序在内存中的镜像
- 数据段:用来存放可执行文件中已初始化全局变量,程序静态分配的变量和全局变量
- BSS段:意为以符号开始的块,包含了程序中未初始化的全局变量
- 堆:存放数组和对象。
- 栈:用户存放程序临时创建的局部变量,有后出先出的特点,是一个寄存、交换临时数据的内存区
7. 解析磁盘中的代码如何在计算机上运行的?
1. 代码存储在磁盘上:
代码通常存储在文件中,可以是二进制可执行文件、文本文件(如源代码文件)、脚本文件等。
文件被存储在磁盘上的特定位置,通常有一个文件系统来管理磁盘上的存储空间。
2. 加载到内存:
要运行一个程序时,操作系统会从磁盘上读取相关的文件,并将其加载到计算机的内存中。
这个过程通常涉及到文件系统的读取和解析,将文件内容读入内存的适当位置,以便后续执行。
3. 执行代码:
一旦代码被加载到内存中,CPU 就可以执行这些指令。对于编译后的二进制文件,CPU 可以直接理解和执行这些指令。而对于脚本文件或源代码文件,可能需要解释器或编译器将其翻译成机器可以执行的指令。
4. 指令执行:
CPU 按照指令集执行加载到内存中的指令。指令可以包括各种操作,例如算术运算、逻辑运算、内存读写操作等。
5. 运行和完成:
程序会根据代码的逻辑进行运行,执行所需的计算和操作。一旦程序运行结束,或者达到了终止条件,它会释放占用的资源,并退出执行。
6. 存储结果:
如果程序需要输出结果,它可以将结果写入内存,并且在需要时将其存储到磁盘上,比如保存到文件中。
9. 总结OOM原理,及处理方法。
OOM即Out Of Memory :内存用完了,当没有足够的内存来为对象分配空间并且垃圾回收期也已经没有空间可回收时,就会出现这个error.
原因是:
- 给应用分配内存太少:比如虚拟机本身可使用的内存太少。
- 运行的应用太多,并且没有释放内存,造成内存泄漏或溢出
解决方法:
- 监控内存,及时发现内存使用异常
- 检查程序是否存在内存泄漏问题,确保程序释放不再需要的内存
- 增加系统的物理内存,提供更多的内存空间
- 给系统增加swap空间
- 对于重要的系统进程,可以设置较高的优先级,以避免OOM Killer选择性地终止这些重要进程。
- 记录系统日志,分析和排查出现OOM的原因,以便未来进行预防和处理
- 设置内核参数限制单个进程所能使用的内存大小
设置内核参数,不允许内存申请过量:
echo 2 > /proc/sys/vm/overcommit_memoryecho 80 > /proc/sys/vm/overcommit_ratioecho 2 > /proc/sys/vm/panic_on_oom
10. 结合进程管理命令,说明进程各种状态。
常见的进程管理命令:
ps:显示当前系统中的进程状态。
用ps aux或者ps -ef即可
top:动态显示系统中各个进程的资源占用情况。
htop:类似于 top 命令,但提供了更多的交互式功能。
pgrep:根据进程名或其他属性查找进程的 PID。
pkill:根据进程名或其他属性杀死进程。
进程状态:
- 创建态:进程在创建时需要申请一个空白PCB(process control block进程控制块),向其中填写 控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无法满足,就无法被调 度运行。
- 就绪状态:进程已准备好,已分配到所需资源,只要分配到CPU就能够立即运行
- 执行状态:进程处于就绪状态被调度后,进程进入执行状态
- 阻塞状态:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就绪状态等待系统调用
- 终止状态:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行
进程更多的状态:
- 运行态(Running):进程正在 CPU 上执行或正在等待 CPU 时间片执行。
- 就绪态(ready):进程已准备好,已分配到所需资源,只要分配到CPU就能够立即运行。
- 睡眠态(Stopped):分为两种,可中断:interruptable,不可中断:uninterruptable
- 僵尸态:结束进程,父进程结束前,子进程不关闭,杀死父进程可以关闭僵死
- 态的子进程
- 停止态:stopped,暂停于内存,但不会被调度,除非手动启动
通过 ps 或 top 等命令查看进程时,可以在进程列表中看到这些不同状态的标识,比如在 STAT 列或者在进程状态字段中显示相应的字符表示不同的状态。
例如,状态码及其含义可能是:
R:运行状态(Running)
S:睡眠状态(Sleeping)
D:不可中断的等待状态(Uninterruptible Sleep)
T:停止状态(Stopped)
Z:僵尸状态(Zombie)
11. 说明IPC通信和RPC通信实现的方式。
IPC通信
IPC是指在同一主机上运行的不同进程之间进行通信的机制。它可以通过多种方式实现:
- pipe:管道,单向传输
- socket 套接字文件,双工通信
- Memory-maped file 文件映射,将文件中的一段数据映射到物理内存,多个进程共享这片内存
- shm shared memory 共享内存
- signal 信号
- Lock 对资源上锁,如果资源已被某进程锁住,则其它进程想修改甚至读取这些资源,都将被阻塞,直到锁被打开
- semaphore 信号量,一种计数器,
RPC通信
不同主机通信
socket=IP和端口号,远程调用
MQ 消息队列,分为生产者和消费者,如:kafka,rabbitMQ,activeMQ
12. 通过mkfifo, cat, 来解释秒杀的并发问题,如何通过队列解决的?最好结合图形。说明消息队列的作用?
13. 总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。
前台和后台作业的区别:
- 前台作业:通过终端启动,且启动后一直占据终端
- 后台作业:可通过终端启动,但启动后即转入后台运行(释放终端)
- 运行中的去前台作业: Ctrl+z
- 尚未启动的作业: COMMAND &
- nohup COMMAND &>/dev/null &
- screen;COMMAND
- tmux;COMMAND
- fg [[%]JOB_NUM]:把指定的后台作业调回前台
- bg [[%]JOB_NUM]:让送往后台的作业在后台继续运行
- kill [%JOB_NUM]: 终止指定的作业
14. 总结内核设计流派及特点。
1. 单内核:
特点:
- 所有操作系统服务和功能都运行在同一个地址空间内。内核包含大量的功能模块,如文件系统、设备驱动、调度器等,直接运行在核心态。
- 高效性:模块之间的直接调用速度快。
- 大而笨重:由于所有功能都在一个内核中,因此内核体积通常较大。
- 例子:Linux 是典型的单内核系统,大多数的 UNIX 操作系统也采用了单内核设计。
2. 微内核:
特点:
- 内核只包含最基本的功能,如调度器、内存管理和进程间通信(IPC)等。其他系统服务如文件系统、设备驱动等被实现为用户空间的进程或服务,运行在用户态。
- 灵活性:可以动态加载和卸载服务,提高了可定制性和可扩展性。
- 复杂的通信开销:由于用户空间服务需要通过IPC与内核通信,可能会引入性能开销。
- 例子:MINIX、QNX 是典型的微内核系统。
3. 混合内核:
特点:
- 结合了单内核和微内核的优点,在一定程度上融合了两种设计思想。包含一些核心服务和功能运行在内核空间,但也有一部分功能运行在用户态。提供了更好的性能和安全性,同时保留了部分灵活性和可扩展性。
- 例子:Windows NT 系统是混合内核,其中一些关键部分运行在核心态,但某些服务和驱动则在用户态。
4. 多级内核:
特点:
- 将硬件抽象层次最小化,提供最小的资源抽象,允许应用程序直接控制硬件资源。为应用程序提供更多的控制权和灵活性,但需要应用程序开发者承担更多的责任。
- 例子:Xok/ExOS 是一个多级内核的例子,允许应用程序更直接地管理硬件资源
15. 总结rocky 启动流程,grub工作流程
CentOS 6 启动流程、grub工作流程
1.POST自检 -- 初始化硬件设备,检查系统外围主要设备
2.BOOTLOADER--grub
- grub stage1: MBR分区的前446字节 ,作用是系统启动装载stage2
- grub stage1.5: MBR之后的扇区,让bootloader能够识别到stage2所在分区的文件系统 ,是1和2之间的桥梁 ,访问/boot分区grub目录下得到stage2文件,载入内存并执行
- grub stage2: 解析grub的配置文件/boot/grub/grub.conf,显示操作系统启动菜单 ,加载内核镜像到内存,然后转交给内核。
3. Kernel:加载内核,调用initramfs.img初始化系统中的各设备并做配置;加载并切换真正的根文件系统(grub.conf中的“root=”所指定)
4.启动第一个进程/sbin/init程序
5./etc/inittab :获取用户级别
6./etc/rc.sysinit:运行系统初始化脚本完成系统初始化
7./etc/rc#.d/Sxxxx:启动需要启动服务,关闭对应需要关闭的服务
8./etc/rc.d/rc.local:开机启动文件,可以自定义开机服务
9.启动终端
16. 手写chkconfig服务脚本,可以实现服务的开始,停止,重启。
[root@rocky8 /etc/init.d]$ cat testrv
#! /bin/bash
#chkconfig: - 98 3
#description:This is a test service script. /etc/init.d/functions
start(){
[ -e /var/lock/subsys/testrv ] && exit || touch /var/lock/subsys/testrv
echo $PATH
action "starting testrv"
sleep 2
}stop(){
[ -e /var/lock/subsys/testrv ] && rm /var/lock/subsys/testrv || exit
action "stopping testrv"
}status(){
[ -e /var/lock/subsys/testrv ] && echo "testrv is running" ||echo "testrv is stopped"
}case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo $"usage: $0 {start|stop|status|restart}"
exit 2
esac
17. 总结systemd服务配置文件
systemd是CentOS 7中的初始化系统,它通过systemd服务管理器来启动、停止和控制系统中的各个服务。以下是systemd服务配置文件的总结:
服务文件存放位置
CentOS 7中的服务配置文件都存放在/usr/lib/systemd/system/和/etc/systemd/system/目录下。其中,/usr/lib/systemd/system/目录下的服务文件是系统自带的服务文件,而/etc/systemd/system/目录下的服务文件是用户自定义的服务文件。用户自定义的服务文件优先级高于系统自带的服务文件。
服务配置文件的命名规则
服务配置文件以.service为扩展名,文件名必须与服务名称一致
systemd unit file文件通常由三部分组成:
- [Unit]:定义与Unit类型无关的通用选项:提供unit的描述信息、unit行为和依赖关系
- [Service]:与特定类型相关的专用选项;此处为Service类型
- [Install]:定义由“systemctl enable”以及"systemctl disable“命令在实现服务启用或禁用时用到的一些选项
- Description:描述信息
- After:定义unit的启动次序,表示当前unit应该晚于哪些unit启动,其功能与Before相反
- Requires:依赖到的其它units,强依赖,被依赖的units无法激活时,当前unit也无法激活
- Wants:依赖到的其它units,弱依赖
- Conflicts:定义units间的冲突关系
- Type:定义影响ExecStart及相关参数的功能的unit进程启动类型
- simple:默认值,这个daemon主要由ExecStart接的指令串来启动,启动后常驻于内存中
- forking:由ExecStart启动的程序透过spawns延伸出其他子程序来作为此daemon的主要服务。原生父程序在启动结束后就会终止
- oneshot:与simple类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中
- dbus:与simple类似,但这个daemon必须要在取得一个D-Bus的名称后,才会继续运作.因此通常也要同时设定BusNname= 才行
- notify:在启动完成后会发送一个通知消息。还需要配合 NotifyAccess 来让 Systemd 接收消息
- idle:与simple类似,要执行这个daemon必须要所有的工作都顺利执行完毕后才会执行。这类的daemon通常是开机到最后才执行即可的服务
- EnvironmentFile:环境配置文件
- ExecStart:指明启动unit要运行命令或脚本的绝对路径
- ExecStartPre: ExecStart前运行
- ExecStartPost: ExecStart后运行
- ExecStop:指明停止unit要运行的命令或脚本
- Restart:当设定Restart=1 时,则当次daemon服务意外终止后,会再次自动启动此服务
- RestartSec: 设置在重启服务( Restart= )前暂停多长时间。 默认值是100毫秒(100ms)。 如果未指定时间单位,那么将视为以秒为单位。 例如设为"20"等价于设为"20s"。
- PrivateTmp:设定为yes时,会在生成/tmp/systemd-private-UUID-NAME.service-XXXXX/tmp/目录
- Alias:别名,可使用systemctl command Alias.service
- RequiredBy:被哪些units所依赖,强依赖
- WantedBy:被哪些units所依赖,弱依赖
- Also:安装本服务的时候还要安装别的相关服务
以下是服务文件的常用操作:
- systemctl start <service>:启动服务。
- systemctl stop <service>:停止服务。
- systemctl restart <service>:重启服务。
- systemctl enable <service>:设置服务开机自启动。
- systemctl disable <service>:取消服务开机自启动。
- systemctl status <service>:查看服务状态信息。
18. 总结system启动流程
Systemd:从 CentOS 7 版本之后开始用 systemd 实现init进程,系统启动和服务器守护进程管理器, 负责在系统启动或运行时,激活系统资源,服务器进程和其它进程
CentOS 7之后启动流程:
1. UEFi 或 BIOS 初始化,运行 POST 开机自检2. 选择启动设备3. 引导装载程序 , centos7 是 grub2, 加载装载程序的配置文件:/etc/grub.d//etc/default/grub/boot/grub2/grub.cfg4. 加载 initramfs 驱动模块(可以实现根文件系统的挂载)5. 加载虚拟根中的内核6. 虚拟根的内核初始化, Centos7 使用 systemd 代替 init, 第一个进程7. 执行 initrd.target 所有单元,包括挂载 /etc/fstab8. 从 initramfs 根文件系统切换到磁盘根目录9. systemd 执行默认 target 配置,配置文件 /etc/systemd/system/default.target10. systemd 执行 sysinit.target 初始化系统及 basic.target 准备操作系统11. systemd 启动 multi-user.target 下的本机与服务器服务12. systemd 执行 multi-user.target 下的 /etc/rc.d/rc.local13. Systemd 执行 multi-user.target 下的 getty.target 及登录服务14. systemd 执行 graphical 需要的服务
19. 总结awk工作原理,awk命令,选项,示例。
19.1 awk基础应用
awk是一个报告生成器,格式化文本输出,通常也称为GNU AWK,可以实现下面功能:
- 文本处理
- 输出格式化的文本报表
- 执行算数运算
- 执行字符串操作
格式:
- awk [options] 'program' var=value file
- awk [options] -f programfile var=value file
Program通常是放在单引号中,可以由三部分组成:
- BEGIN语句块:输出结果的表头,并且可以不对文件做处理只做输出
- 模式匹配的通用语句块
- END语句块:输出结果的末尾
Program格式:
pattern{action statements;..}
pattern决定动作语句何时触发及触发事件,比如:BEGIN,END,正则表达式等
action statements对数据进行处理,放在{}内指明,常见:print printf
awk 常用选项:
-F:指定字段分隔符。
-f:从文件中读取 AWK 脚本。
-v:定义变量并传递给 AWK 脚本。
示例:
#打印/etc/passwd文件内容
[root@rocky8 ~]$ awk ‘{print}’ /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin....
...
#打印/etc/passwd文件内容第1列和第3列
[root@rocky8 ~]$ awk -F":" '{print$1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
#取出磁盘分区利用率
[root@rocky8 ~]$ df | awk -F" +|%" '/\/dev\/sd/{print $1,$5}'
/dev/sda1 26
#取IP地址
[root@rocky8 ~]$ ifconfig eth0|awk '/netmask/{print$2}'
10.0.0.8
19.2 awk变量
awk的变量分为内置变量和自定义变量
常见的内置变量:
- FS:输入字段分隔符,默认为空白字符,相当于-F
- OFS:输出字段分隔符,默认为空白字符
- RS:输入记录分隔符,指定输入时的换行符
- ORS:输入记录分隔符,指定输出时的换行符
- NF:字段数量,即列数
- NR:记录的编号,即行数
示例:
#取出/etc/passwd的最后一列
[root@rocky8 ~]$ awk -F":" '{print $(NF)}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
自定义变量是区分字符大小写的,使用下面方式进行赋值
- -v var=value
- 在program中直接定义
示例:
[root@rocky8 ~]$ awk -v test1=abc 'BEGIN{print test1}'
abc[root@rocky8 ~]$ awk 'BEGIN{test1="abd";print test1}'
abd
[root@rocky8 ~]$ awk 'BEGIN{print test1;test1="abc"}'
19.3 模式PATTERN
根据pattern条件,过滤匹配的行,再做处理
- 如果未指定:空模式,匹配每一行
- /regular expreesion/:仅处理能够模式匹配到的行,需要用/ /括起来
- relatiional expression:关系表达式,结果为真才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值
示例:
[root@rocky8 ~]$ seq 10 | awk 'i=!i'
1
3
5
7
9
- line ranges:行范围,不支持用行号,使用变量NR指定行号 ;/pat1/,/pat2/
示例:
[root@rocky8 ~]$ awk 'NR>=3 && NR<=6{print NR,$0}' /etc/passwd
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
19.4 条件判断
lf-else
语法:
if(condition){statement;...}{else statement}
if(condition){statement;...}else if (condition2) {statement2}lesle if(condition3){statement3}
.....
示例:
[root@rocky8 ~]$ awk -F":" '{if($3<=100)print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
19.5 循环
while
语法:
while (condition){statement;...}
条件为真,进入循环;条件为假,退出循环
示例:
[root@rocky8 ~]$ awk -v i=1 -v sum=0 'BEGIN{while (i<=100){sum+=i;i++};print sum}'
5050
do-while
语法:
do {statement;...}while (condition)
无论真假,至少进行一次循环
for
语法:
for{expr1,expr2,expr3}{statement;...}
for(variable assignment;condition;iteration process){for-body}
for(var in array){for-body} ---- 遍历数组中的元素
示例:
[root@rocky8 ~]$ cat abc.txt
1 2 3 4 5 6 7
[root@rocky8 ~]$ awk '{for(i=1;i<=NF;i++){sum+=i};print sum}' abc.txt
28
20. 总结awk的数组,函数。
20.1 数组
关联数组
格式:
array_name[index-expression] 例: weekadys["mon"]="monday"
遍历数组中的每个元素,使用for循环
示例:
[root@rocky8 ~]$ awk -F":" '{user[$1]=$3}END{for(i in user){print i,user[i]}}' /etc/passwd
adm 3
rpc 32
dnsmasq 982
flatpak 978
sync 5
mail 8
tss 59
gluster 993
20.2 函数
awk的函数分为内置和自定义函数
官方文档
https://www.gnu.org/software/gawk/manual/gawk.html#Functions
常见内置函数
数值处理:
rand() :返回0和1之间一个随机数
srand():配合rand()函数,生成随机数的种子
int():返回整数
示例:
[root@rocky8 ~]$ awk 'BEGIN{srand();for (i=1;i<=10;i++)print int(rand()*100)}'
34
86
88
38
32
24
55
75
74
63
字符串处理:
length([s]):返回指定字符串的长度
sub(r,s[t]):对t字符串搜索r表示模式匹配的内容,并将第一个匹配内容替换为s
gsub(r,s[t]):对t字符串搜索r表示模式匹配的内容,并将全部内容替换为s
split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2
示例:
[root@rocky8 ~]$ netstat -tn | awk '/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count);{print i,count[i]}}'
151.101.1.91 1
调用shell命令
system('cmd')
时间函数
systime() 当前时间到1970年1月1日的秒数
strftime() 指定时间格式
自定义函数
格式:
function name ( parameter,parameter,...){
statements
return expression
}
示例:
[root@rocky8 ~]$ cat func.awk
function max(x,y) {
x>y?var=x:var=y #判断,如果x大于y,则var=x,否则则为y
return var}
BEGIN{print max(a,b)}[root@rocky8 ~]$ awk -v a=25 -v b=24 -f func.awk
25
21. 总结ca管理相关的工具,根据使用场景总结示例。
OpenSSL是一个开源的加密工具库,也是一个命令行工具集,支持SSL和TLS协议,可以用于生成和管理证书和密钥等操作。常用的命令包括:
openssl genrsa:生成RSA密钥对
openssl req:生成证书签名请求
openssl x509:生成自签名证书或签名请求的签名证书
openssl ca:证书颁发机构相关操作,如签署证书请求、吊销证书等
openssl crl:生成证书吊销列表
# 生成证书索引数据库文件touch /etc/pki/CA/index.txt# 指定第一个颁发证书的序列号echo 01 > /etc/pki/CA/serial
cd /etc/pki/CA/(umask 066 ; openssl genrsa -out private/cakey.pem 2048 )
openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 3650 -out/etc/pki/CA/cacert.pem
-new :生成新证书签署请求-x509 :专用于 CA 生成自签证书-key :生成请求时用到的私钥文件-days n :证书的有效期限-out /PATH/TO/SOMECERTFILE: 证书的保存路径
22. 总结对称加密和非对称加密算法和用openssl签发证书步骤
22.1 对称加密
- 加密、解密使用同一个密钥,效率高
- 将原始数据分割成固定大小的块,逐个进行加密
- 密钥过多
- 密钥分发
- 数据来源无法确认
- DES:Data Encryption Standard,56bits
- 3DES:
- AES:Advanced (128, 192, 256bits)
- Blowfish,Twofish
- IDEA,RC6,CAST5
22.2 非对称加密
- 公钥:public key,公开给所有人,主要给别人加密使用
- 私钥:secret key,private key 自己留存,必须保证其私密性,用于自已加密签名
- 特点:用公钥加密数据,只能使用与之配对的私钥解密;反之亦然
- 数据加密:适合加密较小数据,比如: 加密对称密钥
- 数字签名:主要在于让接收方确认发送方身份
- 密钥长,算法复杂
- 加密解密效率低下
- RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的,可实现加密和数字签名
- DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准)
- ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学,比RSA加密算法使用更小的密钥, 提供相当的或更高等级的安全
22.3 使用openssl签发证书步骤
1.生成私钥
(umask 066; openssl genrsa -out /data/test.key 2048)
2.生成证书申请文件
openssl req -new -key /data/test.key -out /data/test.csr
3.在CA签署证书并将证书颁发给请求者
openssl ca -in /data/test.csr -out /etc/pki/CA/certs/test.crt -days 100
4、查看证书中的信息:
openssl x509 -in /PATH/FROM/CERT_FILE -noout -text |issuer|subject|serial|dates# 查看指定编号的证书状态openssl ca -status SERIAL