第四周作业
使用 while read line和 /etc/passwd,计算用户id总和
#!/bin/bash
echo -n "请输入文件 "
read filename
cat $filename | awk -F":" '{print $3}' >long.txt
toral=0
while read line;do
total=$((total+line))
done < long.txt
echo "用户id总和为:$total"
[root@rocky8 soft]$ bash id2.sh
请输入文件 /etc/passwd
用户id总和为:86150
[root@rocky8 soft]$ bash id2.sh
请输入文件 /etc/passwd
用户id总和为:86150
总结索引数组和关联数组,字符串处理,高级变量使用及示例。
索引数组
- 通常是数字索引(通常0开始)标识的数组
- 可以使用索引数组来存储和访问一组有序的值
- 示例
[root@rocky8 ~]$ fruits=("apple" "banana" "orange")
[root@rocky8 ~]$ echo ${fruits[0]} #访问数组元素
apple
[root@rocky8 ~]$ echo ${fruits[*]}
apple banana orange #列出数组所有元素
[root@rocky8 ~]$ echo ${fruits[1]}
banana
引用和查看数组
- ${数组[*]} 查看数组的所有值
- ${数组[x]} 数组特定元素的值
- ${#数组[*]} 数组的值的个数
[root@rocky8 ~]$ echo ${#fruits[*]}
3
[root@rocky8 ~]$ echo ${#fruits[@]}
3
- ${数组[*]} 列出所有数组的下标
[root@rocky8 ~]$ echo ${!fruits[*]}
0 1 2
${数组[*]:7:3} 数组切片
[root@rocky8 ~]$ a=({0..9})
[root@rocky8 ~]$ echo ${a[@]:7:3}
7 8 9
跳过前七个取后3个
字符串处理
基于偏移量取字符串
${#var}:变量var的字符串长度
[root@rocky8 ~]$ var=abcd
[root@rocky8 ~]$ echo ${#var}
4
${var:offset:number} 变量var跳过前offset个字符,取number个字符
[root@rocky8 ~]$ echo ${var:2:3}
cd
跳过前两个字符 取后三个字符
${var:offset}: 取变量var最后offset个字符
${var:-offset:number} 先取最后offset个字符,再去掉后面number个字符
关联数组
下标自定义
关联数组必须先声明,并赋值
[root@rocky8 ~]$ declare -A stauts
[root@rocky8 ~]$ stauts[banzhang]=wangming
[root@rocky8 ~]$ stauts[kedaibiao]=xiaohong
[root@rocky8 ~]$ echo ${stauts[banzhang]}
wangming
通过循环遍历关联数组的下标
[root@rocky8 ~]$ for i in ${stauts[*]};do echo $i;done
xiaohong
wangming
显示所有数组
declare -a
删除数组
unset 数组名
基于模式取子串
echo ${url#*/} : 删除从开头到第一个 / 之间的所有字符
[root@rocky8 ~]$ url=http://www.baidu.com
[root@rocky8 ~]$ echo ${url#*/}
/www.baidu.com
echo ${url##*/} : 删除从开头到最后一个 / 的所有字符
root@rocky8 ~]$ echo ${url##*/}
www.baidu.com
echo ${url% / *} : 删除变量url中从行尾到行首匹配到的字符
[root@rocky8 ~]$ echo ${url%/*}
http:/
查找替换
${a/patter/substr} 查找变量中a中第一次被patten匹配到的字符,并替换为substr
示例:将a变量中的3iu替换为you
[root@rocky8 ~]$ a=nh3iu0289u8765
[root@rocky8 ~]$ echo ${a/3iu/you}
nhyou0289u8765
${a//patter/substr} 查找变量a中的所有被patten匹配到的字符并替换为substr
示例:将a变量中的u替换为c
[root@rocky8 ~]$ echo ${a//u/c}
nh3ic0289c8765
查找删除
${a/patter}:删除变量中被patten匹配到的字符
[root@rocky8 ~]$ echo $a
uyhubjh6e287876
[root@rocky8 ~]$ echo ${a/jh6e}
uyhub287876
${a//patter}: 删除变量中所有被patter匹配到的字符
[root@rocky8 ~]$ echo ${a//7}
uyhubjh6e2886
${a/#patter} :删除变量a中行首被patter匹配到的字符串
${a/%patter} :删除变量中行尾被patter匹配到的字符串
间接变量的引用
示例:a变量引用c变量的值
[root@rocky8 ~]$ a=c
[root@rocky8 ~]$ c=hello
[root@rocky8 ~]$ eval echo \$$a
hello
[root@rocky8 ~]$ echo ${!a}
hello
求10个随机数的最大值与最小值
#!/bin/bash
MAX=$RANDOM
MIN=$MAX
for i in { 1..10 };do
a=$RANDOM
if(( a > MAX ));then
MAX=$a
fi
if((a < MIN));then
MIN=$a
fi
done
echo "最大值是 $MAX"
echo "最小值是 $MIN"
[root@rocky8 ~]$ bash max-min.sh
最大值是 32519
最小值是 360
使用递归调用,完成阶乘算法实现
[root@rocky8 soft]$ cat factorial.sh
#!/bin/bash
fact (){
if [ $1 -le 1 ];then
echo $1
else
echo $(( $1*$(fact $[$1-1])))
fi
}
if [ "$1" -gt 0 ];then
fact $1
else
echo "请输入一个正整数"
fi
解析进程与线程的区别
在 Linux 中,进程和线程是操作系统中用于执行程序的两个基本概念。它们之间的主要区别在于以下几个方面:
1,调度和执行:
-
进程是程序的执行实例,拥有独立的地址空间和系统资源,包括内存、文件描述符、堆栈等。每个进程都由操作系统独立地进行调度和执行。
-
线程是进程内的实体,共享相同的地址空间和系统资源,包括内存、文件描述符等。线程是由操作系统调度和执行的最小单位。
2,创建和销毁开销:
-
创建和销毁进程的开销通常比创建和销毁线程的开销更大,因为进程需要分配独立的地址空间和系统资源。
-
创建和销毁线程的开销相对较小,因为线程共享相同的地址空间和系统资源,只需要分配线程私有的堆栈和寄存器上下文。
3,通信和同步:
-
进程之间的通信和同步需要使用进程间通信(IPC)机制,如管道、消息队列、共享内存等。
-
线程之间的通信和同步相对容易,因为它们共享相同的地址空间,可以直接访问共享的变量和数据结构。
4,并发性:
-
进程是独立的执行实体,进程之间的并发性取决于系统的调度策略。
-
线程是在同一个进程内执行的,因此线程之间的并发性更容易实现。
总的来说,进程和线程是操作系统中用于执行程序的两个基本概念,它们之间的主要区别在于资源的独立性、创建和销毁开销、通信和同步机制以及并发性。
解析进程的结构
1,进程控制块:pcb是内核中用于维护进程信息的数据结构,包含了进程的状态,程序计数器,寄存器,进程标识符,调度信息,内存管理信息,文件系统信息等
2,内存空间:每个进程都有自己独立的内存空间,包括代码段,数据段,堆,栈等,Linux使用虚拟内存管理机制,因此每个进程看到的内存空间都是虚拟的
3,文件描述符:每一个进程都有一个文件描述符表,用于维护进程打开的文件,套接字和其他i/o设备的信息
4,资源和状态:进程拥有一些资源,如打开的文件,网络连接,信号处理器等。此外,进程还有不同的状态,如运行态,就绪台,阻塞态等。
5,父子关系:进程可以拥有父进程和子进程,这种层次结构可以用于进程的管理和通信
结合进程管理命令,说明进程各种状态。
1,运行(running)
- 这表示进程当前正在执行或者等待执行
- 可以使用ps命令查看进程状态,运行状态的进程会显示为R
2,睡眠(sleeping)
- 表示进程当前正在等待某个事件的发生,例如等待i/o操作完成或者等待信号量
- 可以使用ps命令查看进程状态,睡眠状态的进程会显示为S
3,停止(stopped)
- 表示进程被暂停了,通常是因为受到了SIGSTOP,SIGTSTP,SIGTTIN或SIGTTOU信号而被挂起,不会被调度,除非手动启动
- 可以使用ps命令查看进程状态,停止状态的进程会显示为T
4,僵尸(zombie)
- 表示进程已经终止,但其父进程还未对其进行善后处理,回收
- 可以使用ps命令查看进程状态,僵尸状态的进程会显示为z
5,孤儿态
- 子进程在退出前,父进程先退出,这时子进程将成为孤儿进程,
- 通过ps命令查看进程状态,孤儿状态的进程会显示为
6,退出(idle)
- 表示进程当前正在空闲等待,没有要处理的任务,通常情况下,这是指处于空闲状态的CPU核心,没有正在运行的进程
- 在top命令的输出中,状态 I 表示的是空闲状态
说明IPC通信和RPC通信实现的方式。
IPC指设备内不同进程间的通信
1,管道
2,套接字文件
3,文件映射
4,共享内存
5,信号
6,对资源上锁,如果资源已被某进程锁住,则其他进程想修改甚至读取这些资源,都将被阻塞,直到锁被打开
7,信号量
RPC指不同设备间的通信
PRC 远程调用
MQ 消息队列
总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。
前台作业
- 通过终端启动的进程,它会一直占用终端输入和输出,直到进程运行结束或暂停
- 当用户在终端中启动一个命令时,该命令默认会以前台作业的方式运行
- 在前台运行的作业会将输出直接显示在终端上,用户可以与作业进行交互
后台作业
- 后台作业是指在终端中启动的进程,但它不会占用终端的输入和输出,而是在后台静默运行
- 用户可以在命令末尾使用&符号将命令放到后台运行,或者使用CTRL+z暂停一个前台作业并将其放到后台运行
状态转换
-
从前台转到后台:在终端中执行一个命令时,在命令末尾加上 & 符号,该命令就会在后台运行。
-
从后台转到前台:可以使用 fg 命令将一个后台作业切换到前台运行,也可以使用 bg 命令将一个前台作业切换到后台运行。
-
暂停和恢复作业:可以使用 Ctrl+Z 将一个前台作业暂停并放到后台运行,然后使用 fg 命令将其切换回前台继续运行,或者使用 bg 命令让其在后台继续运行。
总的来说,前台作业和后台作业的主要区别在于是否占用终端的输入输出,用户可以通过简单的命令和快捷键在前台和后台之间进行状态转换,以满足不同的运行需求
总结内核设计流派及特点。
单内核设计 :
把所有功能模块集成于同一个程序(linux),支持模块化如进程调度,内存管理,文件系统,硬件驱动等,支持模块的动态装载和卸载
微内核设计:
每种功能模块使用一个单独子系统实现(windows),把一些应用放到用户空间,服务与服务间隔离,单个服务故障或被攻击,也不会导致操作系统挂掉
总结rocky 启动流程,grub工作流程
POST:加电自检,进行硬件自检和启动设备的检测
Bootloader:
grub1阶段:加载MBR0扇区的前446字节启动引导程序
gurb1.5阶段:0扇区后面的字节,boot分区启动
grub2阶段:解析/boot/grub.conf文件内容,加载内核文件和伪根文件系统驱动到内存
kernel:
探测识别系统硬件设备
加载所有硬件驱动程序
以只读方式挂载根文件系统
运行第一个进程init
init初始化
加载/etc/inittab文件,获取默认运行级别
加载/etc/rc.d/rc.sysinit 脚本,系统初始化
加载/etc/rc#.d/S… 脚本,运行系统服务
加载/etc/rc.d/rc.local 脚本,运行用户自定义服务
终端登录
手写chkconfig服务脚本,可以实现服务的开始,停止,重启。
总结ca管理相关的工具,根据使用场景总结示例。
三种策略
match:要求申请填写的信息跟CA设置信息必须一致
optional:可有可无,跟CA设置信息可不一致
supplied:必须填写这项申请信息
创建CA相关文件
mkdir -p /etc/pki/CA/{certs,crl,netwcerts,private}
[root@rocky8 CA]$ tree /etc/pki/CA
/etc/pki/CA (这个目录存放所有CA相关的文件和路径)
├── certs (存放被发布的证书)
├── crl (存放被吊销的证书)
├── netwcerts(新颁发的证书)
└── private (存放CA私钥的路径)
[root@rocky8 CA]$ touch index.txt(记录每个证书的索引信息)
echo 01 > /etc/pki/CA/serial (记录证书的编号)
生成私钥
openssl genrsa -out ATH/TO/PRIVATEKEY.FILE [-aes128] [-aes192] [-aes256] [私钥位数,默认2048位]
示例:生成CA文件的私钥
[root@rocky8 ~]$ (umask 066;openssl genrsa -out /etc/pki/CA/private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
....................+++++
........................................+++++
e is 65537 (0x010001)
注意:CA自己的私钥必须带有.pem后缀
生成CA自签名证书
[root@rocky8 CA]$ openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 3650 -out /etc/pki/CA/cacert.pem
选项说明
-req 申请
-now 生成新证书签署请求
-x509 专用于ca生成自签证书 证书的格式规范
-key 生成请求时用到的私钥文件
-days n 证书的有效期限
-out /etc/pki/CA/casert.pem 证书保存的路径
casert.pem 证书存放的文件 必须带有.pem后缀
查看证书信息
[root@rocky8 CA]$ openssl x509 -in /etc/pki/CA/cacert.pem -noout -text
私钥里提取公钥
[root@rocky8 ~]$ openssl rsa -in /data/nginx.key -pubout -out /data/nginx.pubkey
writing RSA key
[root@rocky8 ~]$ cat /data/nginx.pubkey
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyrj6AccxyRHajdm4fFUp
ZPzfiAo/xuRqRmfr6Tb5U3jh+xD9/2UBjG3s77hhLoKVDEdDJLSHIsz4BV7nw0kN
y0lUlL8pilx5X9YMNHiX1A+JSCj7GnDxqOCkDX3v1sIdPRTG9Cg1JfLs4r0DIHi1
vf1uWZiLHeCqOU+0ImSSHRDFBc01lEp+5nl/XiKz6iBT4VGv6vQnIkRK/9rGLqho
Y/6Zd/OsWqBKSgmwL8r91rJ38JaNXy9JV/pE0OoR/0uiv/IICvkIdlcJPNUoGe3D
dL9pQiw0E19dr0mCTbAtf6uZZjotrGjSOeQkGH+hge/DLQ/b51qp70oGSqhJV0NO
dwIDAQAB
-----END PUBLIC KEY-----
生成用户私钥
(umask 066;openssl genrsa -out /filename)
[root@rocky8 ~]$ (umask 066; openssl genrsa -out /data/test.key 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
.........................+++++
...........................................................+++++
e is 65537 (0x010001)
私钥放到对应服务的相关目录下
生成用户证书请求文件
openssl req -new -key /data/test.key -out /data/test.csr
颁发证书给用户
[root@rocky8 CA]$ openssl ca -in /data/test.csr -out /etc/pki/CA/certs/test.crt -days 100
吊销证书
1.在客户端获取要吊销的证书的serial
[root@rocky8 ~]$ openssl x509 -in /etc/pki/CA/newcerts/02.pem -noout -serial -subject
serial=02
subject=C = CN, ST = sichuan, O = magedu, OU = xiaoshou, CN = www.n86.com
查看证书状态
[root@rocky8 ~]$ openssl ca -status 02
Using configuration from /etc/pki/tls/openssl.cnf
02=Valid (V)
v表示证书有效
2.吊销证书
[root@rocky8 ~]$ openssl ca -revoke /etc/pki/CA/newcerts/02.pem
Using configuration from /etc/pki/tls/openssl.cnf
Revoking Certificate 02.
Data Base Updated
已吊销
[root@rocky8 ~]$ cat /etc/pki/CA/index.txt
V 240829053527Z 01 unknown /C=CN/ST=sichuan/O=magedu/OU=html/CN=www.m49.com
R 240829055709Z 240521061517Z 02 unknown /C=CN/ST=sichuan/O=magedu/OU=xiaoshou/CN=www.n86.com
3.指定第一个吊销证书的编号,注意:第一次更新证书吊销列表前,才需要执行
[root@rocky8 ~]$ echo 01 > /etc/pki/CA/crlnumber
生成吊销列表文件
[root@rocky8 CA]$ openssl ca -gencrl -out /etc/pki/CA/crl.pem
Using configuration from /etc/pki/tls/openssl.cnf
总结对称加密和非对称加密算法和用openssl签发证书步骤
对称加密
-
加密和解密使用同一个密钥,效率高
-
将原始数据切割成固定大小的块,逐个进行加密
缺陷
- 密钥过多
- 密钥分发
- 数据来源无法确认
常见算法
AES,DES,3DES
非对称加密
- 密钥是成对出现的
- 公钥:公开给所有人
- 私钥:自己留存,必须保证私密性,用于加密签名
特点
- 用公钥加密数据,只能使用与之配对的私钥解开 反之亦然
- 数据签名 主要在于让接受方确认发送方的身份
- 密钥长,算法复杂,加密解密效率低下
常见算法
RSA,DSA,ECC
总结对称加密和非对称加密算法和用openssl签发证书步骤
对称加密
-
加密和解密使用同一个密钥,效率高
-
将原始数据切割成固定大小的块,逐个进行加密
缺陷
- 密钥过多
- 密钥分发
- 数据来源无法确认
常见算法
AES,DES,3DES
非对称加密
- 密钥是成对出现的
- 公钥:公开给所有人
- 私钥:自己留存,必须保证私密性,用于加密签名
特点
- 用公钥加密数据,只能使用与之配对的私钥解开 反之亦然
- 数据签名 主要在于让接受方确认发送方的身份
- 密钥长,算法复杂,加密解密效率低下
常见算法
RSA,DSA,ECC
opssl签发证书步骤
1,创建相关目录
(/etc/pki/CA/{crets,netwcerts,crl,private}
touch index.txt , echo 01>/etc/pki/CA/serial)
2,生成私钥
(CA证书文件必须带有.pem后缀)
3,生成自签证书
(cacert.pem)
4,用户生成私钥
(私钥放在对应的服务的目录下)
5,生成用户请求文件
(文件带有.csr后缀)
6,RA核验
7,CA签署
(生成带有.crt文件)
8,获取证书
总结awk工作原理,awk命令,选项,示例
awk工作原理
第一步:执行BEGIN(action)语句
第二步:从文件或标准输入中读取一行,然后执行pattern{action}语句,与sed一样逐行扫描处理,从第一行到最后一行重复这个过程,直到全部被读取完毕
第三步:文件读取完毕后,执行END{action}语句
格式:awk [选项] ‘program’ [var=X] filename
选项:
-F:指定输入的字段分隔符,默认为若干个连续空白符
-v var=X:指定变量赋值
-f filename:指定自定义函数或脚本文件
示例:以:为分隔符,打印passwd文件的第1和3个域字段
[root@rocky8 ~]$ awk -F ":" '{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
示例: 修改FS输入分隔符为 :,并输出时以FS分割
[root@rocky8 ~]$ awk -v FS=':' '{print $1FS$3FS$7}' /etc/passwd
root:0:/bin/bash
bin:1:/sbin/nologin
daemon:2:/sbin/nologin
adm:3:/sbin/nologin
lp:4:/sbin/nologin
sync:5:/bin/sync
shutdown:6:/sbin/shutdown
halt:7:/sbin/halt
示例:打印df除了第一行之外的所有行
[root@rocky8 ~]$ df | awk 'NR!=1{print NR,$0}'
2 devtmpfs 886988 0 886988 0% /dev
3 tmpfs 916616 0 916616 0% /dev/shm
4 tmpfs 916616 9588 907028 2% /run
5 tmpfs 916616 0 916616 0% /sys/fs/cgroup
6 /dev/mapper/rl_rocky8-root 73364480 35906432 37458048 49% /
7 /dev/sda1 1038336 263900 774436 26% /boot
8 /dev/mapper/dgg-logs_lv 5095040 20472 4796040 1% /logs
9 /dev/mapper/dgg-mysql_lv 11254984 30664 10684964 1% /mysql
10 /dev/mapper/rl_rocky8-home 133067284 973556 132093728 1% /home
11 tmpfs 183320 12 183308 1% /run/user/42
12 tmpfs 183320 0 183320 0% /run/user/0
示例:显示passwd文件的列数,以及最后一行的内容
[root@rocky8 ~]$ awk -F: '{print NF,$NF}' /etc/passwd
7 /bin/bash
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
7 /bin/sync
7 /sbin/shutdown
7 /sbin/halt
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
示例:打印df除了第一行之外的其他行
[root@rocky8 ~]$ seq 10 | awk 'NR>=3 && NR<7'
3
4
5
6
示例:打印第七个字段不为/sbin/nologin的行,并且行号小于20的行
[root@rocky8 ~]$ awk -F: '$7 !~ "/sbin/nologin" && NR<=20' /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
示例:awk的if条件判断
[root@rocky8 ~]$ awk -F: '{if($3>=1000 && $3<=1003){print $1,$3}else 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
mail /sbin/nologin
示例:awk的while循环
[root@rocky8 ~]$ awk 'BEGIN{while(i<=100){sum+=i;i++};print sum}'
5050
示例:awk的for循环
root@rocky8 ~]$ awk 'BEGIN{for(i=1;i<=100;i++){sum+=i};print sum}'
5050
总结awk的数组,函数
awk数组为关联数组
关联下标可以为任意字符串,字符串要使用双引号
如果某数组元素不存在,在引用时,awk会自动创建此元素,并将其值初始化为空串
awk函数分为内置函数和自定义函数
数值处理
rand():返回1和0之间随机数
srand():配置rand函数,生成随机数种子
int():返回整数
字符串处理
length(X):返回指定字符串长度
sub(r,s,x):对x字符串搜索r表示模式匹配的内容,并将第一个匹配内容替换为s
gsub(r,s,x):对x字符串搜索r,并将匹配的所有内容替换为s
split(s,array,r):对r为分隔符,切割字符串s,并将切割后的结果保存至array数组
自定义函数
格式
function name(形参){
命令
return var
}