linux学习第六周总结

本周共学习4项内容,简单总结一下

  • shell脚本编程进阶
  • 系统启动和内核管理
  • selinux
  • 文本处理三剑客之awk

一、shell脚本进阶

编程中的逻辑处理:  
    顺序执行
    选择执行
    循环执行  
循环执行  
    将某代码段重复运行多次
    重复运行多少次
        循环次数事先已知
        循环次数事先未知
    有进入条件和退出条件
r, while, until  
for循环
for 变量名 in 列表;do
    循环体
done
执行机制:
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一循环体; 直到列表中的元素耗尽,循环结束
列表生成方式:
(1) 直接给出列表
(2) 整数列表:
    (a) {start..end}
    (b) $(seq [start [step]] end)
(3) 返回列表的命令
    $(COMMAND)
(4) 使用glob,如:*.sh
(5) 变量引用
    $@, $*
例:
[root@magedu ~]# vim userpassword.sh  
#!/bin/sh  
for n in $(seq 1 10);do  
    name=user$n  
    useradd "$name"  
    echo "$(tr -cd [[:alnum:]\!_#@] < /dev/urandom|head   -c 8)"|passwd --stdin $name &> /dev/null
    echo "User creation"
done
exit 0
while循环
while CONDITION; do
    循环体
done
CONDITION:循环控制条件;进入循环之前,先做一次判断;一次循环之后会再次做判断;条件为“true”,则执行一次循环;到条件测试状态为“false”终止循环
因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION为true
退出条件:CONDITION为false
例如打印九九乘法表
[root@magedu ~]# vim 99_while.sh
#!/bin/sh
i=1
while [ $i -le 9 ];do
    j=1
    while [ $j -le $i ];do
        let k=i*j
        echo -en "$i*$j=$k\t"
    let j++
    done
    echo
    let i++
done
until循环
until CONDITION; do
    循环体
done
进入条件: CONDITION 为false
退出条件: CONDITION 为true 
每隔3秒钟到系统上获取已经登录的⽤户的信息;如果发现⽤hacker登录, 则将登录时间和主机记录于⽇志/var/log/login.log中,并退出脚本
[root@magedu ~]# vim userlog.sh
#!/bin/sh
until false;do
    if who |grep "^hacker\>" &> /dev/null;then
        who|grep "^hacker\>" > /var/log/login.log
        break
    fi
    sleep 3
done
循环控制语句continue,
用于循环体中
continue [N]:提前结束第N层的本轮循环,而直接进入下一判断;最内层为第1层
循环控制语句break
用于循环体中
break [N]:提前结束第N层循环,最内层为第1层
循环控制shift命令
shift [n]
用于将参量列表 list 左移指定次数,缺省为左移一次。
参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用到 shift
while循环的特殊用法(遍历文件的每一行)
while read line; do
    循环体
done < /PATH/FROM/SOMEFILE
依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
select循环与菜单
select variable in list
do
    循环体命令
done
select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示 PS3 提示符,等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入被保存在内置变量 REPLY 中
select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环
select 经常和 case 联合使用
与 for 循环类似,可以省略 in list,此时使用位置参量

函数

函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程  
它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分  
函数和shell程序比较相似,区别在于  
Shell程序在子Shell中运行  
而Shell函数在当前Shell中运行。因此在当前Shell中,函数可以对shell中变量进行修改  

定义函数 
函数由两部分组成:函数名和函数体
help function
语法一:
    f_name (){
        ...函数体...
    }
语法二:
    function f_name {
        ...函数体...
    }
语法三:
    function f_name () {
        ...函数体...
}
函数使用
函数的定义和使用:
    可在交互式环境下定义函数
    可将函数放在脚本文件中作为它的一部分
    可放在只包含函数的单独文件中
调用:函数只有被调用才会执行
    调用:给定函数名
    函数名出现的地方,会被自动替换为函数代码
函数的生命周期:被调用时创建,返回时终止
数组
变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组名和索引
    索引:编号从0开始,属于数值索引
    注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0版本之后开始支持
bash的数组支持稀疏格式(索引不连续)
声明数组:
    declare -a ARRAY_NAME
    declare -A ARRAY_NAME: 关联数组
注意:两者不可相互转换
数组赋值
数组元素的赋值
    (1) 一次只赋值一个元素
    ARRAY_NAME[INDEX]=VALUE
    weekdays[0]="Sunday"
    weekdays[4]="Thursday"
    (2) 一次赋值全部元素
    ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
    (3) 只赋值特定元素
    ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)
    (4) 交互式数组值对赋值
    read -a ARRAY
显示所有数组:declare -a
引用数组
引用数组元素
    ${ARRAY_NAME[INDEX]}
    注意:省略[INDEX]表示引用下标为0的元素
引用数组所有元素
    ${ARRAY_NAME[*]}
    ${ARRAY_NAME[@]}
数组的长度(数组中元素的个数)
    ${#ARRAY_NAME[*]}
    ${#ARRAY_NAME[@]}
删除数组中的某元素:导致稀疏格式
    unset ARRAY[INDEX]
删除整个数组
    unset ARRAY
引用数组中的元素:
    数组切片:${ARRAY[@]:offset:number}
        offset: 要跳过的元素个数
        number: 要取出的元素个数
        取偏移量之后的所有元素 
        ${ARRAY[@]:offset}
向数组中追加元素:
    ARRAY[${#ARRAY[*]}]=value
关联数组:
    declare -A ARRAY_NAME
    ARRAY_NAME=([idx_name1]='val1' [idx_name2]='val2‘...)
    注意:关联数组必须先声明再调用
expect介绍
expect 是由Don Libes基于Tcl( Tool Command Language )语言开发的,主要应用于自动化交互式操作的场景,借助Expect处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率
expect 语法:
expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
选项
    -c:从命令行执行expect脚本,默认expect是交互地执行的
    示例:expect -c 'expect "\n" {send "pressed enter\n"}
    -d:可以输出输出调试信息
    示例:expect -d ssh.exp
expect中相关命令
    spawn:启动新的进程
    send:用于向进程发送字符串
    expect:从进程接收字符串
    interact:允许用户交互
    exp_continue 匹配多个字符串在执行动作后加此命令

二、系统启动和内核管理

Linux组成  
    Linux: kernel+rootfs  
    kernel: 进程管理、内存管理、网络管理、驱动程序、文件系统、安全功能  
    rootfs:程序和glibc  
    库:函数集合, function, 调用接口(头文件负责描述)
    程序:二进制执行文件 
内核设计流派:
    单内核(monolithic kernel):Linux
        把所有功能集成于同一个程序
    微内核(micro kernel):Windows, Solaris
        每种功能使用一个单独子系统实现
centos6启动步骤概述
1、上电POST⾃检,加载BIOS的硬件信息,获取第⼀个启动设备
2、读取第⼀个启动设备MBR⾥的引导加载程序(grub)的启动信息
3、加载核⼼操作系统的核⼼信息,核⼼开始解压缩,并尝试驱动所有的硬件设备
4、核⼼执⾏init程序,并获取默认的运⾏信息
5、init程序执⾏/etc/rc.d/rc.sysinit⽂件
6、启动核⼼的外挂模块
7、init执⾏运⾏的各个批处理⽂件(scripts)
8、init执⾏/etc/rc.d/rc.local
9、执⾏/bin/login程序,等待⼀会登录
10、登录之后开始以shell控制主机  

MBR(Master Boot Recorder),我们称之为主引导记录。BIOS是怎样寻找可启动设备的呢?我们知道在分区时,硬盘的第一块扇区512个字节就是存放的MBR,如果该设备是可启动设备,那么该扇区的最后两个字节肯定是55/AA,所以此时在寻找可启动设备时,如果发现该设备的最后两个字节是这个,那么该设备就是可启动设备。BIOS在找到可启动设备以后就会执行其引导代码,因为MBR占据了第一块扇区的512字节,分区表占用了 16*4 =64字节,再加上最后两个标志字节,所以MBR的引导代码就是MBR的前446个字节,当然这446个字节太小了,并不能完成整个操作系统的引导程序,所以这446个字节里面可能存放的就是启动引导程序的一些代码  
GRUB是引导加载程序,将引导操作系统,启动引导器是计算机启动过程中运行的第一个真正的软件,计算机启动时在通过BISO自检后读取并运行引导介质上最前面的扇区即硬盘主引导扇区(MBR)中的启动引导器程序, 这里的扇区中:MBR占据了第一块扇区的512字节,但其实际只占用了其中的446个字节,另外的64个字节交给了DPT(Disk Partition Table硬盘分区表),最后两个字节“55,AA”是分区的结束标志。启动引导器在负责加载启动硬盘分区中的操作系统。如果启动引导器不能正常工作,将导致操作系统不能正常启动,从而整个计算机瘫痪。通常,每个操作系统在安装过程中都要将自带的启动器写在硬盘(MBR),以便能过进行自身的引导。

是系统运行的第一个进程

/etc/inittab    #init&runlevel文件及位置
runlevel:
0   halt(关机)
1   Single User Mode(单用户模式,此模式下可以恢复root密码)
2   Multi User Without NFS(不带网络的多用户模式)
3   命令行多用户模式
4   Unused(未使用,系统保留)
5   X11图形界面模式(与runlevel 3类似,只是多加载了一项X Window)
6   Reboot(重启)
内核编译安装系统
安装开发包组
下载源码文件
.config:准备文本配置文件
make menuconfig:配置内核选项
make [-j #]
make modules_install:安装模块
make install :安装内核相关文件
安装bzImage为/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
编辑grub的配置文件  
编译安装内核示例
tar xf linux-3.10.67.tar.xz -C /usr/src
cd /usr/src
ln -sv linux-3.10.67 linux
cd /usr/src/linux
cp /boot/config-$(uname -r) ./.config
make help
make menuconfig
make -j 2
make modules_install
make install
reboot

三、SElinux

SELinux介绍
SELinux:Security-Enhanced Linux, 是美国国家安全局(NSA=The National Security Agency)和SCC(Secure Computing Corporation)开发的 Linux的一个强制访问控制的安全模块。2000年以GNU GPL发布,Linux内核2.6版本后集成在内核中
DAC:Discretionary Access Control自由访问控制
MAC:Mandatory Access Control 强制访问控制
    DAC环境下进程是无束缚的
    MAC环境下策略的规则决定控制的严格程度
    MAC环境下进程可以被限制的
    策略被用来定义被限制的进程能够使用那些资源(文件和端口)
    默认情况下,没有被明确允许的行为将被拒绝
SELinux策略
对象(object):所有可以读取的对象,包括文件、目录和进程,端口等
主体:进程称为主体(subject)
SELinux中对所有的文件都赋予一个type的文件类型标签,对于所有的进程也赋予各自的一个domain的标签。domain标签能够执行的操作由安全策略里定义
当一个subject试图访问一个object,Kernel中的策略执行服务器将检查AVC (访问矢量缓存Access Vector Cache), 在AVC中,subject和object的权限被缓存(cached),查找“应用+文件”的安全环境。然后根据查询结果允许或拒绝访问
安全策略:定义主体读取对象的规则数据库,规则中记录了哪个类型的主体使用哪个方法读取哪一个对象是允许还是拒绝的,并且定义了哪种行为是充许或拒绝
SELinux有四种工作类型:
    Strict:CentOS 5,每个进程都受到selinux的控制
    targeted:用来保护常见的网络服务,仅有限进程受到selinux控制,只监控容易被入侵的进程,CentOS 4只保护13个服务,CentOS 5保护88个服务
    minimum:CentOS 7,修改的 targeted,只对选择的网络服务
    mls:提供MLS(多级安全)机制的安全性
targeted为默认类型,minimum和mls稳定性不足,未加以应用,strict已不再使用
五个安全元素
    User:指示登录系统的用户类型,进程:如system_u为系统服务进程,是受到管制的,unconfined_u为不管制的进程,用户自己开启的,如 bash,文件:system_u系统进程创建的文件, unconfined_u为用户自已创建的文件
    Role:定义文件,进程和用户的用途:进程:system_r为系统服务进程,受到管制。unconfined_r 为不管制进程,通常都是用户自己开启的,如 bash,文件:object_r
    Type:指定数据类型,规则中定义何种进程类型访问何种文件Target策略基于type实现,多服务共用:public_content_t
    Sensitivity:限制访问的需要,由组织定义的分层安全级别,如unclassified,secret,top,secret, 一个对象有且只有一个   sensitivity,分0-15级,s0最低,Target策略默认使用s0
    Category:对于特定组织划分不分层的分类,如FBI Secret,NSA secret, 一个对象可以有多个categroy, c0-c1023共1024个分类, Target 策略不使用category
配置SELinux:
    SELinux是否启用
    给文件重新打安全标签
    给端口设置安全标签
    设定某些操作的布尔型开关
    SELinux的日志管理
SELinux的状态:
    enforcing:强制,每个受限的进程都必然受限
    permissive:允许,每个受限的进程违规操作不会被禁止,但会被记录于审计日志
    disabled:禁用

四、文本处理三剑客之awk

awk是报告⽣成器,格式化⽂本输出,有多种版本。centos中的是gawk即GNU awk版本。本次实验主 要掌握awk基本⽤法。

awk⼯作原理:
第⼀步:执⾏BEGIN{action;...}语句块中的语句。
第⼆步:从⽂件或标准输⼊(stdin)读取⼀⾏,然后执⾏pattern{action;...}语句块,它逐⾏扫描⽂
件,从第⼀⾏到最后⼀⾏重复这个过程,直到⽂件全部被读取完毕。
第三步:当读⾄输⼊流末尾时,执⾏END{action;...}语句块。
BEGIN语句块在awk开始从输⼊流中读取⾏之前被执⾏,这是⼀个可选的语句块,⽐如变量初始化、打
印输出表格的表头等语句通常可写咋BEGIN语句块中。
END语句块在awk从输⼊流中读完所有的⾏之后被执⾏,⽐如打印所有⾏的分析结果这类信息汇总都是
在END语句块中完成,它也是⼀个可选语句块。
pattern语句块中的通⽤命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执⾏
{print},即打印每⼀个读取到的⾏,awk读取的每⼀⾏都会执⾏该语句块。
print格式:print item1, item2, ...
注意:
逗号分隔符;
输出的各item可以是字符串,也可是数值;当前记录的字段、变量或awk的表达式;
如省略item,相当于print $0。
基本⽤法:
    awk [options] 'program' var=value file ...
    awk [options] -f programfile var=value file ...
    awk [options] 'BEGIN{ action;...} pattern{ action;... } END{ action;... }' file
    ...
awk程序通常由:BEGIN语句块、能够使⽤模式匹配的通⽤语句块、END语句块等三部分组成。
program通常是被单引号或双引号括起来。
选项:
    -F:指明输⼊时⽤到的字段分隔符;
    -v var=value:⾃定义变量
基本格式:
    awk [options] 'program' file
program:表⽰为pattern{action statements;...}
pattern:表⽰部分决定动作语句何时触发及触发事件BEGIN、END;
action statements:表⽰对数据进⾏处理,放置{}内指明print、printf。
分隔符、域和记录:
    awk执⾏时,由分隔符的字段(域)标记$1,$2...$n称为域标  识。$0为所有域,注意:和shell中变量
    $符含义不同;
    ⽂件的每⼀⾏称为记录;
    省略action,则默认执⾏print $0的操作
awk的变量⽤法
内置变量:
    FS:输⼊⾃动分隔符,默认为空⽩字符;
    OFS:输出⾃动分隔符,默认为空⽩字符;
    RS:输⼊记录分隔符,指定输⼊时的换⾏符,原换⾏符仍有效;
    ORS:输出记录分隔符,输出时⽤指定符号代替换⾏符;
    NF:字段数量;
    NR:⾏号;
    FNR:各⽂件分别计数,记录号;
    FILENAME:当前⽂件名;
    ARGC:命令⾏参数的个数
    ARGV:数组,保存的是命令⾏所给定的各参数
awk的格式化输出
格式输出:printf "FORMAT", item1, item2,...
    必须知道FORMAT;
    不会⾃动换⾏,需要显⽰给出换⾏控制符,\n;
    FORMAT中需要分别为后⾯每个item指定格式符   
格式符:与item⼀⼀对应
    %c:显⽰字符的ASCII码;
    %d,%i:显⽰⼗进制整数;
    %e,%E:显⽰科学计数法数值;
    %f:显⽰为浮点数;
    %g,%G:以科学计数法或浮点形式显⽰数值;
    %s:显⽰字符串;
    %u:⽆符号整数;
    %%:显⽰%⾃⾝。
修饰符:
#[.#]:第⼀个#为数字控制显⽰的宽度,第⼆个#表⽰⼩数点后的精度,如%3.1f;
-:左对齐(默认右对齐),如%-15s;
+:显⽰数值的正负号,如%+d。
awk的操作符
    x+y:加法;
    x-y:减法
    x*y:乘法;
    x/y:除法;
    x^y:幂运算;
    x%y:取模(余数)。
赋值操作符:
    =:右边赋值给左边;
    +=:先加,再赋值;
    -=:先减,再赋值;
    *=:先乘,再赋值;
    /=:先除,再赋值;
    %=:先取余,再赋值;
    ^=:先幂运算,再赋值;
    ++:递增操作;
    --:递减操作。
⽐较操作符:
    ==:判断相等;
    !=:判断不等;
    >:判断⼤于;
    >=:判断⼤于等于;
    <:判断⼩于;
    <=:判断⼩于等于。
模式匹配符:
    ~:左边是否和右边匹配包含;
    !~:是否不匹配。
awk PATTERN:awk的模式
PATTERN:根据pattern条件,过滤匹配的⾏,再做处理:
1. 如果未指定:空模式,匹配每⼀⾏;
2. /regular expression/:仅处理能够模式匹配到的⾏,需要⽤//扩起来;
3. relational expression:关系表达式,结果为真,才会被处理;
    真:结果为⾮0值,⾮空字符串都是真;
    假:结果为空字符串或0值都是假。
4. line ranges:⾏范围;
startine,endline:/pat1/,/pat2/不⽀持直接给出数⼦格式。
5. BEGIN/END模式
BEGIN{}:仅在开始处理⽂件中的⽂本之前执⾏⼀次;
END{}:仅在⽂本处理完成之后执⾏⼀次。
常⽤的action分类
    1. Expression:算术,⽐较表达式等;
    2. Control statuments:if,while等;
    3. conmpound statements:组合语句;
    4. input statements:
    5. output statements:print等。
逻辑操作符:
    &&:逻辑与;
    ||:逻辑或;
    !:逻辑⾮。
函数调⽤:
    funciton_name(argu1,argu2,...)  

awk的条件判断
条件表达式:(三⽬表达式)
selector?if-true-expression:if-false-expression
控制语句:
    {statements;...}:组合语句;
    if(condition){statements;...}else {statements;...}
    if(condition1){statement1}else if(condition2){statement2}
    else{statement3}
    while(condition){statements;...}
    do {statements;...} while(condition)
    for(expr1;expr2;expr3) {statements;...}
    break
    continue
    delete array[index]
    delete array
    exit  

awk的循环
    while(condition){statement;...}
        条件为真,进⼊循环,条件为假退出循环;
        使⽤场景:对⼀⾏内的多个字段逐⼀类似处理时使⽤;对数组中的各元素逐⼀处理时使⽤。
    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}
witch语句:
    语法:switch(expresssion){case VALUE1 or /REGEXP/:statement1;case VALUE2 or/REGEXP2/:statement2;...;default:statement}
break、continue、next语句:
    break [n]:结束整个循环默认是最近的⼀次循环;
    continue [n]:跳过本轮循环,执⾏下⼀轮循环;
    next:提前结束对本⾏处理⽽直接进⼊下⼀⾏处理(awk⾃⾝循环)。
awk中的数组。
    1. 关联数组:array[index-expression]
    2. index-expression:
        可使⽤任意字符串;字符串要使⽤双引号括起来
        如果某数组元素事先不存在,在引⽤时,awk会⾃动创建此元素,并将其值初始化为空串
        若要判断数组中是否存在某元素,要使⽤index in array格式进⾏遍历
    3. 若要遍历数组中的每个元素,要使⽤for循环
    4. for(var in array){for-body}
    5. 注意:var会遍历array的每个索引
awk的函数
数值处理:
    rand():返回0和1之间的⼀个随机数,搭配srand()使⽤
字符串处理:
    length([s]):返回指定s字符串的长度
    sub(r,s[t]):对t字符串进⾏搜索r表⽰的模式匹配的内容,并将第⼀个匹配的内容替换为s
    gsub(r,s,[t]):对t字符串进⾏搜索r表⽰的模式匹配的内容,并全部替换为s所表⽰的内容
    split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存⾄array所表⽰的数组中,第⼀
    个索引值为1,第⼆个索引值为2,...
⾃定义函数:
格式:
    function name (parameter1, parameter2, ...){
        statemenets
        return expression
    }  
awk调⽤系统命令和其他功能  
system命令;
    空格是awk中的字符串连接符,如果system中需要使⽤awk中的变量可以使⽤空格分隔,或者说除了awk的变
    量外其他⼀律⽤""引⽤起来。
awk的其他功能:
    将awk程序写成脚本,直接调⽤或执⾏
    向awk脚本传递参数
        格式:awkfile var1=value1 var2=value2 ... Inputfile
    注意:在BEGIN过程中不可使⽤,直到⾸⾏输⼊完成以后,变量才可⽤;可通过-v参数,让awk在执⾏
    EGIN之前得到变量的值;命令⾏中每⼀个指定的变量都需要⼀个-v参数。