1. 使用while read line和/etc/passwd,计算用户id总和。
#!/usr/bin/bash
while read line;do
uid=`echo $line | awk -F ':' '{print $3}'`
sum=$[$sum+$uid]
done < /etc/passwd
echo "用户id总和:$sum"
2. 总结索引数组和关联数组,字符串处理,高级变量使用及示例。
2.1 索引数组
显示所有索引
delcare -a
索引数组赋值
ming=("a" "s" "d") #顺序赋值
ming=( [1]="a" [2]="s" [3]="d") #指定元素赋值
引用索引
${array_name[index]} #如果省略[index]下标将引用下标为0的元素
删除索引数组
unset ARRAY[INDEX]
unset ming[2]
实例
添加元素
ming+=([4]="f")
示例
修改元素
ming[4]="a"
2.2 关联数组
declare -A wang #声明关联数组
wang["xiao"]="abc" #赋值
echo ${wang["xiao"]} #显示数组元素
2.3字符串处理
字符串截取
ming="q1w2e3r4t5y6"
echo ${ming:4} #从索引第 4 个字符开始截取到字符串末尾
echo ${ming:3:6} #从索引第 3 个字符开始,向右截取第 6 个字符
echo ${ming:(-4)} #从字符串末尾开始向左截取第 4 个字符
echo ${ming: -4:-2} #从字符串末尾开始向左截取d第 4 个字符,再从字符串末尾开始向左偏移第 4 个字符
示例
字符串删除截取
qwe="asd123ASD321dsa" #赋值
echo ${qwe#as} #从字符串开头删除 as
echo ${qwe#*AS} #从字符串开头删除第一个匹配的 AS 及前面的所有字符
echo ${qwe##*2} #从字符串开头删除最后一个匹配的 2 及前面的所有字符
echo ${qwe%2*} #从字符串末尾删除第一个匹配 2 及后面的所有字符
echo ${qwe%%2*} #从字符串末尾删除最后一个匹配 2 及后面的所有字符
示例
查找替换
echo ${qwe/123/321} #从开头 123 替换 321
echo ${qwe/%123/321} #从末尾 123 替换 321
echo ${qwe//1/2} #所有 1 替换 2
示例
2.4高级变量
变量未设置 | 变量值为空 | 变量值非空 |
---|---|---|
# unset str3; echo ${str3-"abc"} abc | # str3=""; echo ${str3-"abc"} | # str3=123; echo ${str3-"abc"} 123 |
# unset str3; echo ${str3:-"abc"} abc | # str3=""; echo ${str3:-"abc"} abc | # str3=123; echo ${str3:-"abc"} 123 |
# unset str3; echo ${str3+"abc"} | # str3=""; echo ${str3+"abc"} abc | # str3=123; echo ${str3+"abc"} abc |
# unset str3; echo ${str3:+"abc"} | # str3=""; echo ${str3:+"abc"} | # str3=123; echo ${str3:+"abc"} abc |
# unset str3; echo ${str3="abc"} abc | # str3=""; echo ${str3="abc"} | # str3=123; echo ${str3="abc"} 123 |
# unset str3; echo ${str3?"abc"} bash: str3: abc | # str3=""; echo ${str3?"abc"} | # str3=123; echo ${str3?"abc"} 123 |
# unset str3; echo ${str3:?"abc"} bash: str3: abc | # str3=""; echo ${str3:?"abc"} bash: str3: abc | # str3=123; echo ${str3:?"abc"} 123 |
3. 求10个随机数的最大值与最小值。
#!/usr/bin/bash
q=0
h=10000
echo "随机生成数列表:"
for ((i=0; i<10; i++))
do
max=$((RANDOM%10000))
echo $max
if ((max > q))
then
q=$max
fi
if(( max < h))
then
h=$max
fi
done
echo "最大值为:$q"
echo "最小值为:$h"
4. 使用递归调用,完成阶乘算法实现。
#!/usr/bin/bash
#求 n 的阶乘
factorial() {
if [ $1 -le 1 ]; then
echo 1
else
local n=$(( $1 - 1))
local result=$(factorial $n)
echo $(( $1 * $result ))
fi
}
read -p "请输入一个数字:" m
result=$(factorial $m)
echo "结果为:$result"
#结果如下
请输入一个数字:1
结果为:1
[root@Rocky8 ~]#
[root@Rocky8 ~]# bash tes.sh
请输入一个数字:2
结果为:2
[root@Rocky8 ~]#
[root@Rocky8 ~]# bash tes.sh
请输入一个数字:3
结果为:6
[root@Rocky8 ~]#
[root@Rocky8 ~]# bash tes.sh
请输入一个数字:4
结果为:24
5. 解析进程和线程的区别?
5.1 区别
(1)通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。
(2)线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文。多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定。线程的运行中需要使用计算机的内存资源和CPU。
(3)进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
(4)线程的上下文切换远大于进程间上下文切换的速度。
(5)进程是不可执行的实体,程序是一个没有生命的实体,只有当处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。
5.2 线程和进程的关系以及区别
进程和线程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。线程是指进程内的一个执行单元,也是进程内的可调度实体.
5.3 进程与线程的区别
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
6. 解析进程的结构。
Linux内核中使用 task_struct 结构来表示一个进程,这个结构体保存了进程的所有信息,这个结构体称为进程控制块(PCB)。
内核把进程存放在 任务队列task list 的双向循环列表中,列表中每一项都是task_struct结构。
进程控制块PCB包含信息:
1、进程标识符 name:每个进程都必须有一个唯一的标识符,可以是字符串,也可以是一个数字。
2、进程当前状态 status:说明进程当前所处的状态。为了管理的方便,系统设计时会将相同的状态的进程组成一个队列,如就绪进程队列,等待进程则要根据等待的事件组成多个等待队列,如等待打印机队列、等待磁盘I/O完成队列等等。
3、进程相应的程序和数据地址,以便把PCB与其程序和数据联系起来。
4、进程资源清单。列出所拥有的除CPU外的资源记录,如拥有的I/O设备,打开的文件列表等。
5、进程优先级 priority:进程的优先级反映进程的紧迫程度,通常由用户指定和系统设置。
6、CPU现场保护区 cpustatus:当进程因某种原因不能继续占用CPU时(如等待打印机),释放CPU,这时就要将CPU的各种状态信息保护起来,为将来再次得到处理机恢复CPU的各种状态,继续运行。
7、进程同步与通信机制 用于实现进程间互斥、同步和通信所需的信号量等。
8、进程所在队列PCB的链接字 根据进程所处的现行状态,进程相的PCB参加到不同队列中。PCB链接字指出该进程所在队列中下一个进程PCB的首地址。
9、与进程有关的其他信息。 如进程记账信息,进程占用CPU的时间等。
7. 结合进程管理命令,说明进程各种状态。
R 状态:R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。
D 状态:D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
Z 状态:Z 是 Zombie 的缩写,它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。
S 状态:S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
I 状态:I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。
进程的状态除了上面的状态之外,还有 T 和 t 状态,这两种状态都表示进程处于停止状态,但使得进程停止的原因有所差异,如下所示。
T 状态:由信号触发的停止状态,比如向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接启动的,则需要你用 fg 命令,恢复到前台运行)。
t 状态:由调试跟踪触发的停止状态,当使用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪状态,这其实也是一种特殊的暂停状态,只不过可以用调试器来跟踪并按需要控制进程的运行
8. 说明IPC通信和RPC通信实现的方式。
8.1 IPC通信方式
- 管道(pipe):管道可用于具有亲缘关系的进程间的通信,是一种半双工的方式,数据只能单向流动,允许一个进程和另一个与它有公共祖先的进程之间进行通信。
- 命名管道(named pipe):命名管道克服了管道没有名字的限制,同时除了具有管道的功能外(也是半双工),它还允许无亲缘关系进程间的通信。命令管道在文件系统中有对应的文件名。命令管道通过命令mkfifo或系统调用mkfifo来创建。
- 信号(signal):信号是比较复杂的通信方式,用于通知接收进程有某种事件发生了,除了进程间通信外,进程还可以发送信号给进程本身。
- 消息队列:消息队列是消息的链接表,包括Posix消息队列和system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程可以读走队列中的消息。消息队列克服了信号承载信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
- 共享内存:使得多个进程可以访问同一块内存空间,是最快的IPC形式。是针对其他通信机制运行效率低而设计的。往往与其他通信机制,如信号量结合使用,来达到进程间的同步及互斥。
- 内存映射:内存映射允许任何多个进程间通信每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
- 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
- 套接字(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。
8.2 RPC通信方式
指远程过程调用, 两台服务器,A ,B, A想要调用B服务器上的应用的函数或方法,但是他两不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据,只要调用成功这就称为RPC
调用。
9. 总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。
前台作业:通过终端启动,并且在启动后一直占据终端。
后台作业:启动时与终端无关,或者通过终端启动后转入后台运行(即释放终端),不影响用户继续在终端中工作。
[root@Rocky8 ~]# sleep 100 #前台作业
^Z #ctrl+z,将当前工作移至后台运行
[1]+ Stopped sleep 100
[root@Rocky8 ~]# sleep 200 & #将命令移至后台作业中执行
[2]
[root@Rocky8 ~]# jobs #查看当前所有作业终端
[1]+ Stopped sleep 100
[2]- Running sleep 200 &
[root@Rocky8 ~]# bg 1 #bg 将前台作业放置后台作业
[1]+ sleep 100 &
[root@Rocky8 ~]# jobs #查看
[1]- Running sleep 100 &
[2]+ Running sleep 200 &
[root@Rocky8 ~]# fg 1 #将后台作业放置前台作业
sleep 100
^C #ctrl+c 终止
[root@Rocky8 ~]# jobs #查看
[2]+ Running sleep 200 &
[root@Rocky8 ~]# fg 2
sleep 200
^Z
[2]+ Stopped sleep 200
[root@Rocky8 ~]# jobs
[2]+ Stopped sleep 200
[root@Rocky8 ~]#
10. 总结内核设计流派及特点。
大内核 (Linux,Unix)
大内核则是指将操作系统内核中的所有功能都集成在一起,形成一个庞大的内核。整个内核就是一个大的进程,其中内存管理、进程管理、网络管理等都是这个进程的模块。各个模块之间可以直接通过方法调用进行交互。
优点:性能更高,因为不需要频繁进行进程间通信。
缺点:内核更加复杂,容易出现安全漏洞和稳定性问题。
微内核(Windows)
微内核是指将操作系统内核中的核心功能(如进程管理、内存管理、设备驱动等)作为独立进程运行,各进程间通过IPC(进程间通信)进行通讯。其中微内核相当于一个消息中转站;微内核本身只提供中断处理、任务调度等功能。
优点:内核更加稳定、可靠,同时也更加灵活,可以根据需要动态加载和卸载模块。
降低模块之间的耦合度,某个模块出现问题,不会影响到其他模块。
缺点:由于需要频繁进行进程间通信,会导致性能下降。
11. 总结rocky 启动流程,grub工作流程
11.1 rocky 启动流程
1.硬件上电
2.BIOS自检
3.加载引导启动项
4.在引导项上加载446字节启动引导程序(就是硬盘头部的一串代码)
5.引导程序读取grub.cfg的配置得到启动菜单
6.选择引导菜单
7.内核通过initramfs来加载根文件系统并且是只读的
8.initramfs 通过自身的systemd启动后将真正的根挂载到/sysroot 下
9.initramfs将自身的根文件系统切换成/sysroot下真正的根文件系统
10.内核将重新运行真正根中的systemd初始化操作系统
11.用户的得到指定的运行级别也就是启动目标
grub工作流程
1.加载BIOS的硬件信息与进行自我测试,并依据设置取得第一个可启动的设备
2.读取并执行第一个启动设备内的MBR的bootLoader,例如grup
3.依据bootLoader的设置加载Kernel,kernel检测硬件与加载驱动程序
4.在硬件驱动成功后,Kernel会主动调用init进程,而init进程会取得run-level信息
5.init执行/etc/rc.d/rc.sysinit文件来准备软件执行的操作环境
6.init执行run-level的各个服务的启动
7.init执行/etc/rc.d/rc.local文件
8.init执行终端机模拟程序mingetty来启动login进程,等待用户登录
12. 手写chkconfig服务脚本,可以实现服务的开始,停止,重启。
创建编辑vim /etc/init.d/testsrv文件
#!/bin/bash
#chkcongif: - 96 3
#description: This is test service script
. /etc/init.d/functions
# 启动服务-函数
start(){
[ -e //ver/lock/subsys/testsrv ] && exit || touch /var/lock/subsys/testsrv
echo $PATH
action "Starting testsrv"
sleep 3
}
#暂停服务-函数
stop(){
[ -e /var/lock/subsys/testsrv ] && rm /var/lock/subsys/testsrv || exit
action "Stopping testsrv"
}
status(){
[ -e /var/lock/subsys/testsrv ] && echo "testsrv is running..." || echo"testsrv is stopped"
}
#解析命令行参数
case $1 in
start)
start
;;
syop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 2
esa
启动、暂停服务
[root@Rocky8 ~]# service testsrv start #启动服务
Reloading systemd: [ OK ]
Starting testsrv (via systemctl): [ OK ]
[root@Rocky8 ~]# service testsrv stop #暂停服务
Stopping testsrv (via systemctl): [ OK ]
[root@Rocky8 ~]#
13. 总结systemd服务配置文件
13.1 文件目录
etc/systemd/system
在这个目录中,可以创建和修改自定义的systemd服务单元配置文件。这些配置文件定义了服务的名称、依赖项、启动顺序、运行环境等等
/usr/lib/systemd/system
在这个目录中,通常包含一些系统级别的服务和应用程序的配置文件。这些配置文件通常由软件包管理器在安装过程中自动创建和更新。类似CentOS6中的 /etc/init.d 目录
/usr/local/lib/systemd/system
在这个目录中,可以创建和修改用户级别的服务单元配置文件。这些配置文件只在当前用户的主目录下有效,不会影响其他用户。
/run/systemd/system
在这个目录中,会存储正在运行的服务单元的配置文件。这些配置文件只在当前会话中有效,当系统重新启动时,这些配置文件会被清除。
13.2 基本结构
1.[Unit]
:定义了服务的基本属性,如描述、依赖关系等。
2.[Service]
:定义了服务的执行参数,如启动命令、工作目录、环境变量等。
3.[Install]
:定义了服务的安装信息,如启动级别、依赖关系等。
13.3 常用配置项
Unit
选项 | 描述 |
---|---|
Description | Unit 描述 |
After | 定义 unit 的启动顺序,当前 unit 在 After 指定的的 unit 激活后才启动,与 Before 选项相反 |
Requires · | 当前 unit 依赖的其它 unit。Requires 指定的任意 unit 无法被激活,当前 unit 不会被激活 |
Wants | 当前 unit 依赖的其它 unit。弱依赖 |
Conflicts | 与当前 unit 冲突的 其它 unit |
Service
选项 | 描述 |
---|---|
Type | 影响 ExecStart 功能的 unit 进程启动类型simple :默认值。ExexStart 启动的进程是服务的主进程forking :ExecStart 启动的进程通过 spawn 产生子进程成为服务的主进程。父进程在启动完成后退出oneshot :与 simple 类似,后续 unit 启动完成后退出dbus :与 simple 类似,主进程获取一个 D-Bus 名称后,后续 unit 才会启动notify :与 simple 类似,发送通知消息后才会启动后续 unitidle :与 simple 类似,所有任务完成后才会执行 |
ExecStart | 指定 unit 启动后执行的命令或脚本。ExecStartPre 和 ExecStartPost 指定在 ExexStart 、Type=oneshot 之前和之后执行的自定义命令 |
ExecStop | 指定 unit 停止时执行的命令或脚本 |
ExecReload | 指定 unit 重新加载时执行的命令或脚本 |
Restart | 服务进程退出后重启服务,除非使用 systemctl 停止 |
Install
选项 | 描述 |
---|---|
Alias | unit 别名 |
RequiredBy | 依赖当前 unit 的其它 unit |
WantedBy | 弱依赖 |
Also | 安装当前 unit 需要安装或卸载的其它 unit |
14. 总结systemd启动流程
在我们打开Linux电脑的电源后第一个启动的进程就是init。分配给init进程的PID是1。它是系统其他所有进程的父进程。当一台Linux电脑启动后,处理器会先在系统存储中查找BIOS,之后BIOS会检测系统资源然后找到第一个引导设备,通常为硬盘,然后会查找硬盘的主引导记录(MBR),然后加载到内存中并把控制权交给它,以后的启动过程就由MBR控制。
主引导记录会初始化引导程序(Linux上有两个著名的引导程序,GRUB和LILO,80%的Linux系统在用GRUB引导程序),这个时候GRUB或LILO会加载内核模块。内核会马上查找/sbin下的“init”程序并执行它。从这里开始init成为了Linux系统的父进程。init读取的第一个文件是/etc/inittab,通过它init会确定我们Linux操作系统的运行级别。它会从文件/etc/fstab里查找分区表信息然后做相应的挂载。然后init会启动/etc/init.d里指定的默认启动级别的所有服务/脚本。所有服务在这里通过init一个一个被初始化。在这个过程里,init每次只启动一个服务,所有服务/守护进程都在后台执行并由init来管理。
关机过程差不多是相反的过程,首先init停止所有服务,最后阶段会卸载文件系统。
以上提到的启动过程有一些不足的地方。而用一种更好的方式来替代传统init的需求已经存在很长时间了。也产生了许多替代方案。其中比较著名的有Upstart,Epoch,Muda和Systemd。而Systemd获得最多关注并被认为是目前最佳的方案
15. 总结awk工作原理,awk命令,选项,示例。
15.1 awk工作原理
1.执行 BEGIN{ commands } 语句块中的语句。
2.从文件或标准输入(stdin)读取一行,然后执行 pattern{ commands } 语句块,它逐 行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
3.当读至输入流末尾时,执行 END{ commands } 语句块
格式1: awk 【选项】 '模式或条件{操作} ' 文件名
格式2: awk -f 脚本文件 文件名
15.2 print
逗号分隔符;输出item可以字符串,也可是数值;当前记录的字段、变量或awk的表达式;如省略item,相当于print $0;固定字符符需要用“”引起来,而变量和数值不需要
[root@Rocky8 ~]# seq 10 | awk '{print "hello,awk"}'
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
-F :指定字段分隔符
[root@Rocky8 ~]# awk -F: '{print $1;$3 }' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
.......
15.3 变量
FS
:输入内容字段分隔符,-F
选项优先级更高
[root@Rocky8 ~]# awk -v FS=':' '{print $1FS$3}' /etc/passwd
root:0
bin:1
daemon:2
adm:3
lp:4
sync:5
shutdown:6
halt:7
mail:8
operator:11
......
OFS : 输出内容字段分隔符,默认为空白字符
[root@Rocky8 ~]# awk -v FS=':' -v OFS='+---+' '{print $1,$7}' /etc/passwd
root+---+/bin/bash
bin+---+/sbin/nologin
daemon+---+/sbin/nologin
adm+---+/sbin/nologin
lp+---+/sbin/nologin
sync+---+/bin/sync
shutdown+---+/sbin/shutdown
halt+---+/sbin/halt
..........
RS :输入记录record分隔符,指定输入时的换行符
[root@Rocky8 ~]# awk -v RS=':' '{print}' /etc/passwd
root
x
0
0
root
/root
/bin/bash
bin
x
1
1
bin
/bin
/sbin/nologin
daemon
x
2
2
.............
ORS :输出内容记录分隔符
[root@Rocky8 ~]# awk -v FS=':' -v ORS='\n\n' '{print $1,$4}' /etc/passwd
root 0
bin 1
daemon 2
adm 4
lp 7
............
自定义变量
[root@Rocky8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{print test1,test2}'
test2=hello,gawk
[root@Rocky8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{test1=test2="hello2,gawk";print test1,test2}'
hello2,gawk hello2,gawk
15.4 模式
正则表达式
[root@Rocky8 ~]# df -h | awk '/^\/dev/'
/dev/mapper/rl-root 70G 28G 43G 40% /
/dev/mapper/rl-home 127G 993M 126G 1% /home
/dev/nvme0n1p1 1014M 265M 750M 27% /boot
[root@Rocky8 ~]#
关系表达式
[root@Rocky8 ~]# awk -F: '$NF=="/bin/bash" { print $1,$NF }' /etc/passwd
root /bin/bash
ming /bin/bash
[root@Rocky8 ~]#
15.5 条件判断 if-else
判断是否有以sh结尾文件
[root@Rocky8 ~]# awk -F: '{ if($NF~"sh$") { printf "%-20s yes\n", $1 } else { printf "%-20s no\n", $1 } }' /etc/passwd
root yes
bin no
daemon no
adm no
lp no
sync no
..................
15.6 while 循环
[root@Rocky8 ~]# awk -v i=1 -v sum=0 'BEGIN{while(i<=100){sum+=i;i++};print sum }'
5050
15.7 for 循环
[root@Rocky8 ~]# awk 'BEGIN{total=0;for(i=1;i<=100;i++){total+=i};print total}'
15.8 continue 和 break
continue 中断本次循环
break 中断整个循环
[root@Rocky8 ~]# awk 'BEGIN{for(i=1;i<=100;i++){if(i==50)continue;sum+=i};print sum}'
5000
[root@Rocky8 ~]# awk 'BEGIN{for(i=1;i<=100;i++){if(i==50)break;sum+=i};print sum}'
1225
15.9 next
next 可以提前结束对本行处理而直接进入下一行处理(awk自身循环)
[root@Rocky8 ~]# awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd
root 0
daemon 2
lp 4
shutdown 6
mail 8
games 12
ftp 14
nobody 65534
polkitd 998
.............
16. 总结awk的数组,函数。
16.1 数组
awk的数组是关联数组
判断索引数组是否存在
[root@Rocky8 ~]# awk 'BEGIN{array["i"]="x";array["j"]="y" ; print "i" in array, "y" in arrat }'
1 0
遍历数组
[root@Rocky8 ~]# awk 'BEGIN { weekdays[0]="Sunday"; weekdays[1]="Monday"; weekdays[2]="Tuesday"; for(i in weekdays) { print i, weekdays[i]}}'
0 Sunday
1 Monday
2 Tuesday
16.2 函数
数组处理
rand():返回0和1之间随机数
srand():配合rand()函数,生成随机数的种子
int():返回整数
[root@Rocky8 ~]# awk 'BEGIN{srand();print rand()}'
0.288817
[root@Rocky8 ~]# awk 'BEGIN{srand();print rand()}'
0.339596
[root@Rocky8 ~]# awk 'BEGIN{srand();print rand()}'
0.869703
[root@Rocky8 ~]# awk 'BEGIN{srand();print rand()}'
0.298125
[root@Rocky8 ~]# awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int (rand()*100)}'
47
50
56
52
39
53
14
78
10
2
字符串处理
length([s]):返回字符串 s 的长度
gsub(r, s [, t]):替换所有匹配的子串
sub(r, s [, t]):替换第一个匹配的子串
split(s, a [, r [, seps]]):指定分隔符 seps 分割字符串 s,并将分割后的子串存储在数组 a 中,第一个索引值为1,第二个索引值为2,......
[root@Rocky8 ~]# awk -F: '{print length($1)}' /etc/passwd #统计用户名长度
4
3
6
3
2
...............
时间函数
#systime():返回时间戳
#strftime(format [, timestamp]):格式化时间戳
[root@Rocky8 ~]# awk 'BEGIN{print systime()}'
1710230429
[root@Rocky8 ~]# awk 'BEGIN{print strftime("%Y-%m-%d-%H:%M",systime())}'
2024-03-12-16:00
17. 总结ca管理相关的工具,根据使用场景总结示例。
CA和证书
加密算法和协议
对称加密算法
加密和解密使用同一个秘钥。
特性
加密、解密使用同一个秘钥,效率高
将原始数据分割为固定大小的块,逐个加密
缺陷
秘钥过多
秘钥分发
数据来源无法确认
常见算法
DES、3DES、AES、IDEA、Blowfish、RC6
非对称加密算法
秘钥是成对出现
公钥:public key,公开给所有人,主要给别人加密使用
私钥:secret key,private key,自己留存,必须保证其私密性,用于自己加密签名
特点:用公钥加密数据,只能使用与之配对的私钥解密;反之亦然
功能
数据加密:适合加密较小数据;如:加密对称秘钥
数字签名:主要在于让接收方确认发送方身份
缺点
密钥长,算法复杂
加密解密,效率低下
常见算法
RSA、DSA、ECC
场景
非对称加密实现加密
接收者:生成公钥/秘钥对,公开公钥,保密秘钥
发送者:使用接收者的公钥来加密消息,将加密后的消息发送给接收者
接收者:使用秘钥来解密消息
非对称加密实现数字签名
发送者:生成公钥/秘钥对,公开公钥,保密秘钥,使用秘钥加密消息,将加密后的消息发送给接收者
如下使用 OpenSSL 生成自签名证书和私钥
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
18. 总结对称加密和非对称加密算法和用openssl签发证书步骤
18.1签发CA证书
创建签发CA证书所需要目录和文件
mkdir -p /etc/pki/CA/{certs,crl,newcerts,private} #创建需要目录文件
tree /etc/pki/CA #查看刚刚创建目录文件
生成证书索引数据库文件
touch /etc/pki/CA/index.txt
指定第一个颁发证书的序列号
echo 0F > /etc/pki/CA/serial
18.2创建私有CA证书
生成CA私钥
cd /etc/pki/CA;(umask 688; openssl genrsa -out private/cakey.pem 2048)
[root@Rocky8 CA]# cat private/cakey.pem #查看生成私钥
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA4BRyNV5YhTFCE9z5z3AH8Ak0J8CAeiq3BLnCo/sLQmDdNZxb
RkoFyDOASttO5Ds8ML1kc9o42RelvgmpNJegluA/RDnFHsIiG0sALAB0lKVcJvaA
PARx1jOyQdzg6w4aphghFpoTDV2BnrnI5fqeMRBzWSV2Y63RfblgwWiO31AP8Hca
V8qKcP0CCuA9ciivle43CM1B3Zp0Xsr+LUHLZzbAdnHFH0ali2A201KYBvWPqN6h
qoEkaE+edxzE75OkiEfsT7nRfiq05pckCTvjvw6wsWIcVSa4/RUgjOH3qWYleiDt
nTRd+Lc/n5eOxGmeNHihqJrS+lhpGV2A9rY1BwIDAQABAoIBAQC15sMjobf4P5ll
aH/+LfKzn7UQBAwHoD87/dQMq9FjDCDm0UujDpoNAAnIOqmbSp687jHqfh6h1Ll+
QHd0MxZxBA83wjHLm0p2n3a/QYth066wDnDgx7blbMfrAXQwPB3T8UiDAYYv1lVP
1X9Jeh4KtFD+8BNgLY0fI2pw9wDsM5vaZRgdTCwVyZbC+Si9dtX/+c+8Dcfr4Tz1
yo0/OplkqREYi2UnbxIeurVDYv9gZ0ANYbunfJLoNZ4Eij1/6RursaWzuiP74VX0
......................
生成CA自签名证书
openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 3650 -out /etc/pki/CA/cacert.pem
示例:
查看生成CA证书
openssl x509 -in /etc/pki/CA/cacert.pem -noout -text
示例
生成自己的私钥,私钥应该存放至各应用相应目录下
(umask 066;openssl genrsa -out /etc/test.key 2048)
生成证书申请文件
openssl req -new -key /etc/test.key -out /etc/test.csr
#其中国家代码、省名、公司名必须和CA中一致
CA签发证书
openssl ca -in /etc/test.csr -out /etc/pkI/CA/certs/test.crt -days 100