Linux系统管理

    磁盘分区及文件系统管理

    RAID

    LVM

    网络属性管理

    程序包管理

    sed and awk

    进程查看和管理

    内核管理(编译和安装)

    系统启动流程

    定制、编译内核、busybox

    系统安装:kickstart,dhcp, pxe

    shell脚本编程

    

Linux磁盘及文件系统管理


    CPU, Memory(RAM), I/O

    

    I/O: Disks, Ehtercard

        Disks: 持久存储数据

        

            接口类型:

                IDE(ata):并口,133MB/s

                SCSI:并口,Ultrascsi320, 320MB/S, UltraSCSI640, 640MB/S

                SATA:串口,6gbps

                SAS:串口,6gbps

                USB:串口,480MB/s

                

                并口:同一线缆可以接多块设备;

                    IDE:两个,主,从

                    SCSI:

                        宽带:16-1

                        窄带:8-1

                串口:同一线缆只可以接一个设备;

                

                iops:io per second

                

            硬盘:机械硬盘,固态硬盘;

                

                机械硬盘:

                    track:磁道

                    sector:扇区,512bytes

                    cylinder:柱面

                        分区划分基于柱面:

                    

                    平均寻道时间:

                    

                        5400rpm, 7200rpm, 10000rpm, 15000rpm

                        

    Linux的哲学思想:一切皆文件;

        

        设备类型:

            块(block):随机访问,数据交换单位是“块”;

            字符(character):线性访问,数据交换单位是“字符”;

            

        设备文件:FHS

            /dev

                设备文件:关联至设备的驱动程序;设备的访问入口;

                    

                    设备号:

                        major:主设备号,区分设备类型;用于标明设备所需要的驱动程序;

                        minor:次设备号,区分同种类型下的不同的设备;是特定设备的访问入口;

                        

                    mknod命令:

                        make block or character special files

                        

                        mknod  [OPTION]...  NAME  TYPE  [MAJOR  MINOR]

                        

                            -m MODE:创建后的设备文件的访问权限;

            

            设备文件名:ICANN

            

            磁盘:

                IDE: /dev/hd[a-z]

                    例如:/dev/hda, /dev/hdb

                SCSI, SATA, USB, SAS: /dev/sd[a-z]

                

                分区:

                    /dev/sda#:

                        /dev/sda1, ...

                

                注意:CentOS 6和7统统将硬盘设备文件标识为/dev/sd[a-z]#                        

                    

                引用设备的方式:

                    设备文件名

                    卷标

                    UUID

                    

    磁盘分区:MBR, GPT

        MBR:0 sector

            Master Boot Record

            

                分为三部分:

                    446bytes:bootloader, 程序,引导启动操作系统的程序;

                    64bytes:分区表,每16bytes标识一个分区,一共只能有4个分区;

                        4主分区

                        3主1扩展:

                            n逻辑分区

                    2bytes:MBR区域的有效性标识;55AA为有效;

                    

            主分区和扩展分区的标识:1-4

            逻辑分区:5+

                    

        课外作业:GPT

    

    fdisk命令:

        

        1、查看磁盘的分区信息:

            fdisk -l [-u] [device...]:列出指定磁盘设备上的分区情况;

            

        2、管理分区

            fdisk  device

            

            fdisk提供了一个交互式接口来管理分区,它有许多子命令,分别用于不同的管理功能;所有的操作均在内存中完成,没有直接同步到磁盘;直到使用w命令保存至磁盘上;

            

            常用命令:

                n:创建新分区

                d:删除已有分区

                t:修改分区类型

                l:查看所有已经ID

                w:保存并退出

                q:不保存并退出

                m:查看帮助信息

                p:显示现有分区信息

                

            注意:在已经分区并且已经挂载其中某个分区的磁盘设备上创建的新分区,内核可能在创建完成后无法直接识别;

                

                查看:cat  /proc/partitions

                通知内核强制重读磁盘分区表:

                    CentOS 5:partprobe [device]

                    CentOS 6,7:partx, kpartx

                        partx -a [device]

                        kpartx -af [device]

                        

                分区创建工具:parted, sfdisk;

                

    创建文件系统:

        

        格式化:低级格式化(分区之前进行,划分磁道)、高级格式化(分区之后对分区进行,创建文件系统)

        

            元数据区,数据区

                元数据区:

                    文件元数据:inode (index node)

                        大小、权限、属主属组、时间戳、数据块指针

                        

                    符号链接文件:存储数据指针的空间当中存储的是真实文件的访问路径;

                    设备文件:存储数据指针的空间当中存储的是设备号(major, minor);

                    

            bitmap index:位图索引

            

        VFS: Virtual File System

            Linux的文件系统: ext2(无日志功能), ext3, ext4, xfs, reiserfs, btrfs

            光盘:iso9660

            网络文件系统:nfs, cifs

            集群文件系统:gfs2, ocfs2

            内核级分布式文件系统:ceph

            windows的文件系统:vfat, ntfs

            伪文件系统:proc, sysfs, tmpfs, hugepagefs

            Unix的文件系统:UFS, FFS, JFS

            交换文件系统:swap

            用户空间的分布式文件系统:mogilefs, moosefs, glusterfs

            

        文件系统管理工具:

            创建文件系统的工具

                mkfs

                    mkfs.ext2, mkfs.ext3, mkfs.ext4, mkfs.xfs, mkfs.vfat, ...

            检测及修复文件系统的工具

                fsck

                    fsck.ext2, fsck.ext3, ...

            查看其属性的工具

                dumpe2fs, tune2fs

            调整文件系统特性:

                tune2fs

                

    链接文件:访问同一个文件不同路径;

        硬链接:指向同一个inode的多个文件路径;

            特性:

                (1) 目录不支持硬链接;

                (2) 硬链接不能跨文件系统;

                (3) 创建硬链接会增加inode引用计数;

            

            创建:

                ln  src  link_file

        

        符号链接:指向一个文件路径的另一个文件路径;

            特性:

                (1) 符号链接与文件是两人个各自独立的文件,各有自己的inode;对原文件创建符号链接不会增加引用计数;

                (2) 支持对目录创建符号链接,可以跨文件系统;

                (3) 删除符号链接文件不影响原文件;但删除原文件,符号指定的路径即不存在,此时会变成无效链接;

                

                注意:符号链接文件的大小是其指定的文件的路径字符串的字节数;

                

            创建:

                ln -s  src link_file

                

                -v:verbose

                

回顾:磁盘、磁盘分区、文件系统


    CentOS 6,7:/dev/sd[a-z]#

    管理分区:fdisk, parted, sfdisk

    创建文件系统:

    Linux文件系统类型:ext2, ext3, ext4, xfs, reiserfs, iso9660, swap

    文件系统的组织结构中的术语:

        block groups, block, inode table, inode, inode bitmap, block bitmap, superblock

        

磁盘和文件系统管理


            

    文件系统管理工具:

        创建文件系统的工具

            mkfs

                mkfs.ext2, mkfs.ext3, mkfs.ext4, mkfs.xfs, mkfs.vfat, ...

        检测及修复文件系统的工具

            fsck

                fsck.ext2, fsck.ext3, ...

        查看其属性的工具

            dumpe2fs, tune2fs

        调整文件系统特性:

            tune2fs    

            

    内核级文件系统的组成部分:

        文件系统驱动:由内核提供

        文件系统箮理工具:由用户空间的应用程序提供

        

    ext系列文件系统的管理工具:

        mkfs.ext2, mkfs.ext3, mkfs.ext4

        

        mkfs -t ext2 = mkfs.ext2

        

        ext系列文件系统专用管理工具:mke2fs

            mke2fs [OPTIONS]  device

                -t {ext2|ext3|ext4}:指明要创建的文件系统类型

                    mkfs.ext4 = mkfs -t ext4 = mke2fs -t ext4

                -b {1024|2048|4096}:指明文件系统的块大小;

                -L LABEL:指明卷标;

                -j:创建有日志功能的文件系统ext3;

                    mke2fs -j = mke2fs -t ext3 = mkfs -t ext3 = mkfs.ext3

                -i #:bytes-per-inode,指明inode与字节的比率;即每多少字节创建一个Indode;

                -N #:直接指明要给此文件系统创建的inode的数量;

                -m #:指定预留的空间,百分比;

                

                -O [^]FEATURE:以指定的特性创建目标文件系统;

                

            e2label命令:卷标的查看与设定

                查看:e2label device

                设定:e2label device LABEL

                

            tune2fs命令:查看或修改ext系列文件系统的某些属性

                adjust tunable filesystem parameters on ext2/ext3/ext4 filesystems;

                注意:块大小创建后不可修改;

                

                tune2fs [OPTIONS] device

                    -l:查看超级块的内容;

                    

                    修改指定文件系统的属性:

                        -j:ext2 --> ext3;

                        -L LABEL:修改卷标;

                        -m #:调整预留空间百分比;

                        -O [^]FEATHER:开启或关闭某种特性;

                        

                        -o [^]mount_options:开启或关闭某种默认挂载选项

                            acl

                            ^acl

                            

            dumpe2fs命令:显示ext系列文件系统的属性信息

                dumpe2fs  [-h] device

                

            用于实现文件系统检测的工具

                

                因进程意外中止或系统崩溃等 原因导致写入操作非正常终止时,可能会造成文件损坏;此时,应该检测并修复文件系统; 建议,离线进行;

                

                ext系列文件系统的专用工具:

                    e2fsck : check a Linux ext2/ext3/ext4 file system

                        e2fsck [OPTIONS]  device

                            -y:对所有问题自动回答为yes;

                            -f:即使文件系统处于clean状态,也要强制进行检测;

                            

                    fsck:check and repair a Linux file system

                        -t fstype:指明文件系统类型;

                            fsck -t ext4 = fsck.ext4

                        -a:无须交互而自动修复所有错误;

                        -r:交互式修复;        

        

    CentOS 6如何使用xfs文件系统:

        # yum  -y  install  xfsprogs

            

        事先:

                # cd /etc/yum.repos.d/

                # wget  http://172.16.0.1/centos6.7.repo

                # mv CentOS-Base.repo CentOS-Base.repo.bak

                

        创建:mkfs.xfs

        检测:fsck.xfs         

        

    blkid命令:

        blkid device

        blkid  -L LABEL:根据LABEL定位设备

        blkid  -U  UUID:根据UUID定位设备

        

    swap文件系统:

        Linux上的交换分区必须使用独立的文件系统;

            且文件系统的System ID必须为82;

            

        创建swap设备:mkswap命令

            mkswap [OPTIONS]  device

                -L LABEL:指明卷标

                -f:强制

                

    Windows无法识别Linux的文件系统; 因此,存储设备需要两种系统之间交叉使用时,应该使用windows和Linux同时支持的文件系统:fat32(vfat);

        # mkfs.vfat device

        

    文件系统的使用:

        首先要“挂载”:mount命令和umount命令

        

        根文件系统这外的其它文件系统要想能够被访问,都必须通过“关联”至根文件系统上的某个目录来实现,此关联操作即为“挂载”;此目录即为“挂载点”;

        

            挂载点:mount_point,用于作为另一个文件系统的访问入口;

                (1) 事先存在;

                (2) 应该使用未被或不会被其它进程使用到的目录;

                (3) 挂载点下原有的文件将会被隐藏;

            

        mount命令:

            mount  [-nrw]  [-t vfstype]  [-o options]  device  dir

            

                命令选项:

                    -r:readonly,只读挂载;

                    -w:read and write, 读写挂载;

                    -n:默认情况下,设备挂载或卸载的操作会同步更新至/etc/mtab文件中;-n用于禁止此特性;

                    

                    -t vfstype:指明要挂载的设备上的文件系统的类型;多数情况下可省略,此时mount会通过blkid来判断要挂载的设备的文件系统类型;

                    

                    -L LABEL:挂载时以卷标的方式指明设备;

                        mount -L LABEL dir

                        

                    -U UUID:挂载时以UUID的方式指明设备;

                        mount -U UUID dir

                        

                -o options:挂载选项

                    sync/async:同步/异步操作;

                    atime/noatime:文件或目录在被访问时是否更新其访问时间戳;

                    diratime/nodiratime:目录在被访问时是否更新其访问时间戳;

                    remount:重新挂载;

                    acl:支持使用facl功能;

                        # mount -o acl  device dir

                        # tune2fs  -o  acl  device

                        

                    ro:只读

                    rw:读写

                    dev/nodev:此设备上是否允许创建设备文件;

                    exec/noexec:是否允许运行此设备上的程序文件;

                    auto/noauto:

                    user/nouser:是否允许普通用户挂载此文件系统;

                    suid/nosuid:是否允许程序文件上的suid和sgid特殊权限生效;                    

                    

                    defaults:Use default options: rw, suid, dev, exec, auto, nouser, async, and relatime.

                    

            一个使用技巧:

                可以实现将目录绑定至另一个目录上,作为其临时访问入口;

                    mount --bind  源目录  目标目录

                    

            查看当前系统所有已挂载的设备:

                # mount

                # cat  /etc/mtab

                # cat  /proc/mounts

                

            挂载光盘:

                mount  -r  /dev/cdrom  mount_point

                

                光盘设备文件:/dev/cdrom, /dev/dvd

                

            挂载U盘:

                事先识别U盘的设备文件;

                

            挂载本地的回环设备:

                # mount  -o  loop  /PATH/TO/SOME_LOOP_FILE   MOUNT_POINT

                

        umount命令:

            umount  device|dir

            

            注意:正在被进程访问到的挂载点无法被卸载;

                查看被哪个或哪些进程所战用:

                    # lsof  MOUNT_POINT

                    # fuser -v  MOUNT_POINT

                    

                    终止所有正在访问某挂载点的进程:

                    # fuser  -km  MOUNT_POINT

                    

    交换分区的启用和禁用:

        创建交换分区的命令:mkswap

        

        启用:swapon

            swapon  [OPTION]  [DEVICE]

                -a:定义在/etc/fstab文件中的所有swap设备;

                

        禁用:swapoff

            swapoff DEVICE

            

    设定除根文件系统以外的其它文件系统能够开机时自动挂载:/etc/fstab文件

        每行定义一个要挂载的文件系统及相关属性:

            6个字段:

                (1) 要挂载的设备:

                    设备文件;

                    LABEL

                    UUID

                    伪文件系统:如sysfs, proc, tmpfs等

                (2) 挂载点

                    swap类型的设备的挂载点为swap;

                (3) 文件系统类型;

                (4) 挂载选项

                    defaults:使用默认挂载选项;

                    如果要同时指明多个挂载选项,彼此间以事情分隔;

                        defaults,acl,noatime,noexec

                (5) 转储频率

                    0:从不备份;

                    1:每天备份;

                    2:每隔一天备份;

                (6) 自检次序

                    0:不自检;

                    1:首先自检,通常只能是根文件系统可用1;

                    2:次级自检

                    ...

                

            mount  -a:可自动挂载定义在此文件中的所支持自动挂载的设备;

            

    两个命令:df和du

        df命令:

            df [OPTION]... [FILE]...

                -l:仅显示本地文件的相关信息;

                -h:human-readable

                -i:显示inode的使用状态而非blocks

                

        du命令:

            du [OPTION]... [FILE]...

                -s: sumary

                -h: human-readable

                

    练习:

        1、创建一个10G的分区,并格式化为ext4文件系统;

            (1) block大小为2048;预留空间为2%,卷标为MYDATA;

            (2) 挂载至/mydata目录,要求挂载时禁止程序自动运行,且不更新文件的访问时间戳;

            (3) 可开机自动挂载;

            

        2、创建一个大小为1G的swap分区,并启动之;

        

回顾:文件系统管理

    管理工具:mkfs, mke2fs, e2label, tune2fs, dumpe2fs, e2fsck, blkid

        mkfs.xfs, mkfs.vfat, fsck

        mkswap, swapon, swapoff

        mount, umount, fuser, lsof

        df, du

        

    fstab文件:

        设备     挂载点     文件系统类型     挂载选项      转储频率      自检次序

        

    文件系统:

        目录:文件

            元数据:inode, inode table

            数据:data blocks

                下级文件或目录的文件名与其inode对应关系

                

                dentry

            

        文件名:上级目录;

        

        删除文件:将此文件指向的所有data block标记为未使用状态;将此文件的inode标记为未使用;

        复制和移动文件:

            复制:新建文件;

            移动文件:

                在同一文件系统:改变的仅是其路径;

                在不同文件系统:复制数据至目标文件,并删除原文件;

                

        符号链接:

            权限:lrwxrwxrwx

        硬链接:指向同一个inode;


bash脚本编程


    脚本文件格式:

        第一行,顶格:#!/bin/bash

        注释信息:#

        代码注释:

        缩进,适度添加空白行;

        

    语言:编程语法格式,库,算法和数据结构

    编程思想:

        问题空间 --> 解空间

        

    变量:

        局部变量

        本地变量

        环境变量

        

        位置参数变量

        特殊变量

        

    数据类型:字符型、数值型

        弱类型:字符型

        

    算术运算:

        +, -, *, /, %, **

        

        let  VAR=expression

        VAR=$[expression]

        VAR=$((expression))

        VAR=$(expr argu1 argu2 argu3)

        

        注意:有些时候乘法符号需要转义;

        

        增强型赋值:

            变量做某种算术运算后回存至此变量中;

                let i=$i+#

                let i+=#

                

            +=,-=,*=, /=, %=

            

            自增:

                VAR=$[$VAR+1]

                let  VAR+=1

                let  VAR++

                

            自减:

                VAR=$[$VAR-1]

                let  VAR-=1

                let  VAR--

                

    练习:

        1、写一个脚本

            计算/etc/passwd文件中的第10个用户和第20个用户的id号之和;

                id1=$(head -10  /etc/passwd | tail -1  | cut  -d:  -f3)

                id2=$(head -20   /etc/passwd | tail -1  | cut  -d:  -f3)

                

            

        2、写一个脚本

            计算/etc/rc.d/init.d/functions和/etc/inittab文件的空白行数之和;

            

                grep "^[[:space:]]*$"   /etc/rc.d/init.d/functions | wc -l

                

    条件测试:

        判断某需求是否满足,需要由测试机制来实现;

        

        如何编写测试表达式以实现所需的测试:

            (1) 执行命令,并利用命令状态返回值来判断;

                0:成功

                1-255:失败

            (2) 测试表达式

                test  EXPRESSION

                [ EXPRESSION ]

                [[ EXPRESSION ]]

                

                注意:EXPRESSION两端必须有空白字符,否则为语法错误;

                

        bash的测试类型:

            数值测试

            字符串测试

            文件测试

            

            数值测试:数值比较

                -eq:是否等于; [ $num1 -eq $num2 ]

                -ne:是否不等于;

                -gt:是否大于;

                -ge:是否大于等于;

                -lt:是否小于;

                -le:是否小于等于;

                

            字符串测试:

                ==:是否等于;

                >:是否大于;

                <:是否小于;

                !=:是否不等于;

                =~:左侧字符串是否能够被右侧的PATTERN所匹配;

                

                -z "STRING":判断指定的字串是否为空;空则为真,不空则假;

                -n "STRING":判断指定的字符串是否不空;不空则真,空则为假;

                

                注意:

                    (1) 字符串要加引用;

                    (2) 要使用[[ ]];

                    

            文件测试:

                存在性测试

                    -a  FILE

                    -e  FILE

                        文件的存在性测试,存在则为真,否则则为假;

                存在性及类型测试

                    -b  FILE:是否存在并且为 块设备 文件;

                    -c  FILE:是否存在并且为 字符设备 文件;

                    -d  FILE:是否存在并且为 目录文件;

                    -f  FILE:是否存在并且为 普通文件;

                    -h  FILE或 -L  FILE:是否存在并且为 符号链接文件;

                    -p FILE:是否存在且为 命名管道文件;

                    -S  FILE:是否存在且为 套接字文件;

                文件权限测试:

                    -r  FILE:是否存在并且 对当前用户可读;

                    -w  FILE:是否存在并且 对当前用户可写;

                    -x  FILE:是否存在并且 对当前用户可执行;

                特殊权限测试:

                    -u  FILE:是否存在并且 拥有suid权限;

                    -g  FILE:是否存在并且 拥有sgid权限;

                    -k  FILE:是否存在并且 拥有sticky权限;

                文件是否有内容:

                    -s  FILE:是否有内容;

                时间戳:

                    -N FILE:文件自从上一次读操作后是否被修改过;

                从属关系测试:

                    -O  FILE:当前用户是否为文件的属主;

                    -G  FILE:当前用户是否属于文件的属组;

                双目测试:

                    FILE1  -ef  FILE2:FILE1与FILE2是否指向同一个文件系统的相同inode的硬链接;

                    FILE1  -nt  FILE2:FILE1是否新于FILE2;

                    FILE1  -ot  FILE2:FILE1是否旧于FILE2;

                    

            组合测试条件:

                逻辑运算:

                    第一种方式:

                        COMMAND1 && COMMAND2

                        COMMAND1 || COMMAND2

                        ! COMMAND

                        

                        [ -O FILE ] && [ -r FILE ]

                        

                    第二种方式:

                        EXPRESSION1  -a  EXPRESSION2

                        EXPRESSION1  -o  EXPRESSION2

                        ! EXPRESSION

                        

                        [ -O FILE -a -x FILE ]

                        

                练习:将当前主机名称保存至hostName变量中;

                    主机名如果为空,或者为localhost.localdomain,则将其设置为www.magedu.com

                    

                    hostName=$(hostname)

                    

                    [ -z "$hostName" -o "$hostName" == "localhost.localdomain" -o "$hostName" == "localhost" ] && hostname www.magedu.com                     

                    

        脚本的状态返回值:

            默认是脚本中执行的最后一条件命令的状态返回值;

            自定义状态退出状态码:

                exit  [n]:n为自己指定的状态码;

                    注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;

                    

    向脚本传递参数:

        位置参数变量

        

        myscript.sh  argu1 argu2

            引用方式:

                $1,  $2, ..., ${10}, ${11}, ...

                

            轮替:

                shift  [n]:位置参数轮替;

                

        练习:写一脚本,通过命令传递两个文本文件路径给脚本,计算其空白行数之和;

            

            #!/bin/bash

            #

            file1_lines=$(grep "^$" $1 | wc -l)

            file2_lines=$(grep "^$" $2 | wc -l)


            echo "Total blank lines: $[$file1_lines+$file2_lines]"    

            

    特殊变量:

        $0:脚本文件路径本身;

        $#:脚本参数的个数;

        $*:所有参数

        $@:所有参数


    过程式编程语言的代码执行顺序:

        顺序执行:逐条运行;

        选择执行:

            代码有一个分支:条件满足时才会执行;

            两个或以上的分支:只会执行其中一个满足条件的分支;

        循环执行:

            代码片断(循环体)要执行0、1或多个来回;

            

        选择执行:

            单分支的if语句:

                if  测试条件

                then

                    代码分支

                fi

            

            双分支的if语句:

                if  测试条件; then

                    条件为真时执行的分支

                else

                    条件为假时执行的分支

                fi

                

        示例:通过参数传递一个用户名给脚本,此用户不存时,则添加之;

            #!/bin/bash

            #

            if ! grep "^$1\>" /etc/passwd &> /dev/null; then

                useradd $1

                echo $1 | passwd --stdin $1 &> /dev/null

                echo "Add user $1 finished."

            fi    

            

            #!/bin/bash

            #

            if [ $# -lt 1 ]; then

                echo "At least one username."

                exit 2

            fi


            if ! grep "^$1\>" /etc/passwd &> /dev/null; then

                useradd $1

                echo $1 | passwd --stdin $1 &> /dev/null

                echo "Add user $1 finished."

            fi        

                

            #!/bin/bash

            #

            if [ $# -lt 1 ]; then

                echo "At least one username."

                exit 2

            fi


            if grep "^$1\>" /etc/passwd &> /dev/null; then

                echo "User $1 exists."

            else

                useradd $1

                echo $1 | passwd --stdin $1 &> /dev/null

                echo "Add user $1 finished."

            fi            

            

        练习1:通过命令行参数给定两个数字,输出其中较大的数值;

            #!/bin/bash

            #

            if [ $# -lt 2 ]; then

                echo "Two integers."

                exit 2

            fi


            if [ $1 -ge $2 ]; then

                echo "Max number: $1."

            else

                echo "Max number: $2."

            fi


            

            #!/bin/bash

            #


            if [ $# -lt 2 ]; then

                echo "Two integers."

                exit 2

            fi


            declare -i max=$1


            if [ $1 -lt $2 ]; then

                max=$2

            fi


            echo "Max number: $max."

                    

        练习2:通过命令行参数给定一个用户名,判断其ID号是偶数还是奇数;

        练习3:通过命令行参数给定两个文本文件名,如果某文件不存在,则结束脚本执行;

            都存在时返回每个文件的行数,并说明其中行数较多的文件;

        

        

    练习:

        1、创建一个20G的文件系统,块大小为2048,文件系统ext4,卷标为TEST,要求此分区开机后自动挂载至/testing目录,且默认有acl挂载选项;

            (1) 创建20G分区;

            (2) 格式化:

                mke2fs -t ext4 -b 2048 -L 'TEST' /dev/DEVICE

            (3) 编辑/etc/fstab文件

            LABEL='TEST'     /testing     ext4     defaults,acl     0 0


        2、创建一个5G的文件系统,卷标HUGE,要求此分区开机自动挂载至/mogdata目录,文件系统类型为ext3;


        3、写一个脚本,完成如下功能:

            (1) 列出当前系统识别到的所有磁盘设备;

            (2) 如磁盘数量为1,则显示其空间使用信息;

                否则,则显示最后一个磁盘上的空间使用信息;

                if [ $disks -eq 1 ]; then

                    fdisk -l /dev/[hs]da

                else

                    fdisk -l $(fdisk -l /dev/[sh]d[a-z] | grep -o "^Disk /dev/[sh]d[a-]" | tail -1 | cut -d' ' -f2)

                fi



bash脚本编程之用户交互:

    read [option]... [name ...]

        -p 'PROMPT'

        -t TIMEOUT


    bash -n /path/to/some_script

        检测脚本中的语法错误


    bash -x /path/to/some_script

        调试执行


    示例:

        #!/bin/bash

        # Version: 0.0.1

        # Author: MageEdu

        # Description: read testing


        read -p "Enter a disk special file: " diskfile

        [ -z "$diskfile" ] && echo "Fool" && exit 1


        if fdisk -l | grep "^Disk $diskfile" &> /dev/null; then

            fdisk -l $diskfile

        else

            echo "Wrong disk special file."

            exit 2

        fi


回顾:

    mount/umount, fstab配置文件、ext文件系统基础原理、read、bash


        /etc/fstab


        ext:super block, GDT, inode table, block bitmap, inode bitmap


        dumpe2fs -h, tune2fs -l


        软链接:l,


回顾:

    mount/umount, fstab配置文件、ext文件系统基础原理、read、bash


        /etc/fstab


        ext:super block, GDT, inode table, block bitmap, inode bitmap


        dumpe2fs -h, tune2fs -l


        软链接:l,


RAID:

    Redundant Arrays of Inexpensive Disks

                        Independent


    Berkeley: A case for Redundent Arrays of Inexpensive Disks RAID


        提高IO能力:

            磁盘并行读写;

        提高耐用性;

            磁盘冗余来实现


        级别:多块磁盘组织在一起的工作方式有所不同;

        RAID实现的方式:

            外接式磁盘阵列:通过扩展卡提供适配能力

            内接式RAID:主板集成RAID控制器

            Software RAID:


    级别:level

        RAID-0:0, 条带卷,strip;

        RAID-1: 1, 镜像卷,mirror;

        RAID-2

        ..

        RAID-5:

        RAID-6

        RAID10

        RAID01


        RAID-0:

            读、写性能提升;

            可用空间:N*min(S1,S2,...)

            无容错能力

            最少磁盘数:2, 2+


        RAID-1:

            读性能提升、写性能略有下降;

            可用空间:1*min(S1,S2,...)

            有冗余能力

            最少磁盘数:2, 2+


        RAID-4:

            1101, 0110, 1011


        RAID-5:

            读、写性能提升

            可用空间:(N-1)*min(S1,S2,...)

            有容错能力:1块磁盘

            最少磁盘数:3, 3+


        RAID-6:

            读、写性能提升

            可用空间:(N-2)*min(S1,S2,...)

            有容错能力:2块磁盘

            最少磁盘数:4, 4+


        

        混合类型

            RAID-10:

                读、写性能提升

                可用空间:N*min(S1,S2,...)/2

                有容错能力:每组镜像最多只能坏一块;

                最少磁盘数:4, 4+

            RAID-01:


            RAID-50、RAID7


            JBOD:Just a Bunch Of Disks

                功能:将多块磁盘的空间合并一个大的连续空间使用;

                可用空间:sum(S1,S2,...)


        常用级别:RAID-0, RAID-1, RAID-5, RAID-10, RAID-50, JBOD


        实现方式:

            硬件实现方式

            软件实现方式


            CentOS 6上的软件RAID的实现:

                结合内核中的md(multi devices)


                mdadm:模式化的工具

                    命令的语法格式:mdadm [mode] <raiddevice> [options] <component-devices>

                        支持的RAID级别:LINEAR, RAID0, RAID1, RAID4, RAID5, RAID6, RAID10;


                    模式:

                        创建:-C

                        装配: -A

                        监控: -F

                        管理:-f, -r, -a


                    <raiddevice>: /dev/md#

                    <component-devices>: 任意块设备



                    -C: 创建模式

                        -n #: 使用#个块设备来创建此RAID;

                        -l #:指明要创建的RAID的级别;

                        -a {yes|no}:自动创建目标RAID设备的设备文件;

                        -c CHUNK_SIZE: 指明块大小;

                        -x #: 指明空闲盘的个数;


                        例如:创建一个10G可用空间的RAID5;


                    -D:显示raid的详细信息;

                        mdadm -D /dev/md#


                    管理模式:

                        -f: 标记指定磁盘为损坏;

                        -a: 添加磁盘

                        -r: 移除磁盘


                    观察md的状态:

                        cat /proc/mdstat


                    停止md设备:

                        mdadm -S /dev/md#


                watch命令:

                    -n #: 刷新间隔,单位是秒;


                    watch -n# 'COMMAND'


        练习1:创建一个可用空间为10G的RAID1设备,要求其chunk大小为128k,文件系统为ext4,有一个空闲盘,开机可自动挂载至/backup目录;

        练习2:创建一个可用空间为10G的RAID10设备,要求其chunk大小为256k,文件系统为ext4,开机可自动挂载至/mydata目录;


    博客作业:raid各级别特性;


LVM2:


    LVM: Logical Volume Manager, Version: 2


    dm: device mapper,将一个或多个底层块设备组织成一个逻辑设备的模块;

        /dev/dm-#


    /dev/mapper/VG_NAME-LV_NAME

        /dev/mapper/vol0-root

    /dev/VG_NAME/LV_NAME

        /dev/vol0/root


    pv管理工具:

        pvs:简要pv信息显示

        pvdisplay:显示pv的详细信息


        pvcreate /dev/DEVICE: 创建pv


    vg管理工具:

        vgs

        vgdisplay


        vgcreate  [-s #[kKmMgGtTpPeE]] VolumeGroupName  PhysicalDevicePath [PhysicalDevicePath...]

        vgextend  VolumeGroupName  PhysicalDevicePath [PhysicalDevicePath...]

        vgreduce  VolumeGroupName  PhysicalDevicePath [PhysicalDevicePath...]

            先做pvmove


        vgremove


    lv管理工具:

        lvs

        lvdisplay


        lvcreate -L #[mMgGtT] -n NAME VolumeGroup


        lvremove /dev/VG_NAME/LV_NAME


    扩展逻辑卷:

        # lvextend -L [+]#[mMgGtT] /dev/VG_NAME/LV_NAME

        # resize2fs /dev/VG_NAME/LV_NAME


    缩减逻辑卷:

        # umount /dev/VG_NAME/LV_NAME

        # e2fsck -f /dev/VG_NAME/LV_NAME

        # resize2fs /dev/VG_NAME/LV_NAME #[mMgGtT]

        # lvreduce -L [-]#[mMgGtT] /dev/VG_NAME/LV_NAME

        # mount


    快照:snapshot

        lvcreate -L #[mMgGtT] -p r -s -n snapshot_lv_name original_lv_name


    练习1:创建一个至少有两个PV组成的大小为20G的名为testvg的VG;要求PE大小为16MB, 而后在卷组中创建大小为5G的逻辑卷testlv;挂载至/users目录;


    练习2: 新建用户archlinux,要求其家目录为/users/archlinux,而后su切换至archlinux用户,复制/etc/pam.d目录至自己的家目录;


    练习3:扩展testlv至7G,要求archlinux用户的文件不能丢失;


    练习4:收缩testlv至3G,要求archlinux用户的文件不能丢失;


    练习5:对testlv创建快照,并尝试基于快照备份数据,验正快照的功能;



文件系统挂载使用:

    挂载光盘设备:

        光盘设备文件:

            IDE: /dev/hdc

            SATA: /dev/sr0


            符号链接文件:

                /dev/cdrom

                /dev/cdrw

                /dev/dvd

                /dev/dvdrw


        mount -r /dev/cdrom /media/cdrom

        umount /dev/cdrom


    dd命令:convert and copy a file

        用法:

            dd if=/PATH/FROM/SRC of=/PATH/TO/DEST

                bs=#:block size, 复制单元大小;

                count=#:复制多少个bs;


            磁盘拷贝:

                dd if=/dev/sda of=/dev/sdb


            备份MBR

                dd if=/dev/sda of=/tmp/mbr.bak bs=512 count=1


            破坏MBR中的bootloader:

                dd if=/dev/zero of=/dev/sda bs=256 count=1


        两个特殊设备:

            /dev/null: 数据黑洞;

            /dev/zero:吐零机;


    博客作业:lvm基本应用,扩展及缩减实现;            

                    

回顾:lvm2, dd

    lvm: 边界动态扩展或收缩;快照;

        pv --> vg --> lv

            PE:

            LE:


    dd: 复制


btrfs文件系统:

    技术预览版


    Btrfs (B-tree, Butter FS, Better FS), GPL, Oracle, 2007, CoW;

    ext3/ext4, xfs


    核心特性:

        多物理卷支持:btrfs可由多个底层物理卷组成;支持RAID,以联机“添加”、“移除”,“修改”;

        写时复制更新机制(CoW):复制、更新及替换指针,而非“就地”更新;

        数据及元数据校验码:checksum

        子卷:sub_volume

        快照:支持快照的快照;

        透明压缩:


    文件系统创建:

        mkfs.btrfs

            -L 'LABEL'

            -d <type>: raid0, raid1, raid5, raid6, raid10, single

            -m <profile>: raid0, raid1, raid5, raid6, raid10, single, dup

            -O <feature>

                -O list-all: 列出支持的所有feature;


        属性查看:

            btrfs filesystem show


        挂载文件系统:

            mount -t btrfs /dev/sdb MOUNT_POINT


        透明压缩机制:

            mount -o compress={lzo|zlib} DEVICE MOUNT_POINT


    子命令:filesystem, device, balance, subvolume


回顾:

        RAID:Level

        LVM:volume

        btrfs:了解;

        

压缩和解压缩工具和bash脚本编程;


    压缩比

        目的:时间 换 空间

            CPU的时间 --> 磁盘空间

            

    compress/uncompress, .Z

    gzip/gunzip,  .gz

    bzip2/bunzip2,  .bz2

    xz/unxz,  .xz

    lzma/unlzma, lzma

    zip/unzip

    tar, cpio

    

    1、gzip/gunzip/zcat

        gzip, gunzip, zcat - compress or expand files

        

        gzip  [OPTION]...  FILE...

            -d:解压缩,相当于gunzip;

            -#:指定压缩比,默认是6;数字越大压缩比越大(1-9);

            -c:将压缩结果输出至标准输出;

                gzip  -c  FILE > /PATH/TO/SOMEFILE.gz

                

    2、bzip2/bunzip2/bzcat

        

        bzip2  [OPTION]...  FILE...

            -d:解压缩

            -#:指定压缩比;默认是6;数字越大压缩比越大(1-9);

            -k:keep,保留原文件;

                

    3、xz/unxz/xzcat

          lzma/unlzma/lzcat

          

        xz  [OPTION]...  FILE...

            -d:解压缩

            -#:指定压缩比;默认是6;数字越大压缩比越大(1-9);

            -k:保留原文件;

            

    归档:tar, cpio

        

        tar命令:

            tar  [OPTION]...  FILE...

            

            (1) 创建归档

                -c -f /PATH/TO/SOMEFILE.tar  FILE...

                -cf /PATH/TO/SOMEFILE.tar  FILE...

                

            (2) 展开归档

                -xf  /PATH/FROM/SOMEFILE.tar

                -xf  /PATH/FROM/SOMEFILE.tar  -C  /PATH/TO/SOMEDIR

                

            (3) 查看归档文件的文件列表

                -tf  /PATH/TO/SOMEFILE.tar

                

        归档完成后通常需要压缩,结果此前的压缩工具,就能实现压缩多个文件了;

            (4) 归档压缩

                -z:gzip2

                    -zcf   /PATH/TO/SOMEFILE.tar.gz  FILE...

                    解压缩并展开归档:-zxf  /PATH/TO/SOMEFILE.tar.gz

                    

                -j:bzip2

                    -jcf

                    -jxf

                    

                -J: xz

                    -Jcf

                    -Jxf

                    

    zip:

        zip/unzip

            后缀名:.zip

            

    练习:下载redis-3.0.2.tar.gz,展开至/tmp目录;而后得新创建压缩为xz格式;

        lftp  172.16.0.1/pub/Sources/sources/redis

        lftp> mget redis-3.0.2.tar.gz

    

bash脚本编程之用户交互:


    脚本参数

    

    用户交互:通过键盘输入数据,从而完成变量赋值操作;

        read [option]... [name ...]

            -p 'PROMPT'

            -t TIMEOUT


            #!/bin/bash

            #

            read -p "Enter a username: " name

            [ -z "$name" ] && echo "a username is needed." && exit 2


            read -p "Enter password for $name, [password]: " password

            [ -z "$password" ] && password="password"


            if id $name &> /dev/null; then

                echo "$name exists."

            else

            useradd $name

                echo "$password" | passwd --stdin $name &> /dev/null

                echo "Add user $name finished."

            fi            

                        

    bash -n /path/to/some_script

        检测脚本中的语法错误


    bash -x /path/to/some_script

        调试执行


    示例:

        #!/bin/bash

        # Version: 0.0.1

        # Author: MageEdu

        # Description: read testing


        read -p "Enter a disk special file: " diskfile

        [ -z "$diskfile" ] && echo "Fool" && exit 1


        if fdisk -l | grep "^Disk $diskfile" &> /dev/null; then

            fdisk -l $diskfile

        else

            echo "Wrong disk special file."

            exit 2

        fi

                

Linux任务计划、周期性任务执行


    未来的某时间点执行一次某任务:at, batch

    周期性运行某任务:crontab

        执行结果:会通过邮件发送给用户

        

        ~]# netstat  -tnlp

         ~ ]# ss -tnl

        

    本地电子邮件服务:

        smtp:simple mail transmission protocol

        pop3:Post Office Procotol

        imap4:Internet Mail Access Procotol

        

        mail命令:

            mailx - send and receive Internet mail

            

                MUA:Mail User Agent, 用户收发邮件的工具程序;

                

                mailx  [-s 'SUBJECT']  username[@hostname]

                    邮件正文的生成:

                        (1) 交互式输入;. 单独成行可以表示正文结束;Ctrl+d提交亦可;

                        (2) 通过输入重定向;

                        (3) 通过管道;

                        

    at命令:

        at  [OPTION]... TIME

        

            TIME:

                HH:MM [YYYY-mm-dd]

                noon,midnight, teatime

                tomorrow

                now+#

                    UNIT:minutes, hours, days, OR weeks

                    

            at的作业有队列,用单个字母表示,默认都使用a队列;

        

            常用选项:

                -l:查看作业队列,相当于atq

                -f /PATH/FROM/SOMEFILE:从指定文件中读取作业任务,而不用再交互式输入;

                -d:删除指定的作业,相当于atrm;

                -c:查看指定作业的具体内容;

                -q QUEUE:指明队列;

                

            注意:作业执行结果是以邮件发送给提交作业的用户;

            

    batch命令:

        batch会让系统自行选择在系统资源较空闲的时间去执行指定的任务;

        

    周期性任务计划:cron

        服务程序:

            cronie:主程序包,提供了crond守护进程及相关辅助工具;

            

        确保crond守护进程(daemon)处于运行状态:

            CentOS 7:

                systemctl  status  crond.service

                    Active: active (running) ... ...

                    

            CentOS 6:

                service  crond  status

                    ... is running.

                    

        向crond提交作业的方式不同于at,它需要使用专用的配置文件,此文件有固定格式,不建议使用文本编辑器直接编辑此文件;要使用crontab命令;

            cron任务分为两类:

                系统cron任务:主要用于实现系统自身的维护;

                    手动编辑:/etc/crontab文件

                用户cron任务:

                    命令:crontab命令

            

            系统cron的配置格式:/etc/crontab

                SHELL=/bin/bash

                PATH=/sbin:/bin:/usr/sbin:/usr/bin

                MAILTO=root


                # For details see man 4 crontabs


                # Example of job definition:

                # .---------------- minute (0 - 59)

                # |  .------------- hour (0 - 23)

                # |  |  .---------- day of month (1 - 31)

                # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...

                # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat

                # |  |  |  |  |

                # *  *  *  *  * user-name  command to be executed

                

                注意:

                    (1) 每一行定义一个周期性任务,共7个字段;

                        *  *  *  *  * : 定义周期性时间

                        user-name : 运行任务的用户身份

                        command to be executed:任务

                    (2) 此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量;

                    (3) 执行结果邮件发送给MAILTO指定的用户

                    

            用户cron的配置格式:/var/spool/cron/USERNAME

                SHELL=/bin/bash

                PATH=/sbin:/bin:/usr/sbin:/usr/bin

                MAILTO=root


                # For details see man 4 crontabs


                # Example of job definition:

                # .---------------- minute (0 - 59)

                # |  .------------- hour (0 - 23)

                # |  |  .---------- day of month (1 - 31)

                # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...

                # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat

                # |  |  |  |  |

                # *  *  *  *  *   command to be executed    

                

                注意:

                    (1) 每行定义一个cron任务,共6个字段;

                    (2) 此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量;

                    (3) 邮件发送给当前用户;

            

            时间表示法:

                (1) 特定值;

                    给定时间点有效取值范围内的值;

                        注意:day of week和day of month一般不同时使用;

                (2) *

                    给定时间点上有效取值范围内的所有值;表“每..”

                (3) 离散取值:,

                    在时间点上使用逗号分隔的多个值;

                        #,#,#

                (4) 连续取值:-

                    在时间点上使用-连接开头和结束

                        #-#

                (5) 在指定时间点上,定义步长:

                    /#:#即步长;

                    

                    注意:

                        (1) 指定的时间点不能被步长整除时,其意义将不复存在;

                        (2) 最小时间单位为“分钟”,想完成“秒”级任务,得需要额外借助于其它机制;

                            定义成每分钟任务:而在利用脚本实现在每分钟之内,循环执行多次;

                    

            示例:

                (1) 3 * * * *:每小时执行一次;每小时的第3分钟;

                (2) 3 4 * * 5:每周执行一次;每周5的4点3分;

                (3) 5 6 7 * *:每月执行一次;每月的7号的6点5分;

                (4) 7 8 9 10 *:每年执行一次;每年的10月9号8点7分;

                (5) 9 8 * * 3,7:每周三和周日;

                (6) 0 8,20 * * 3,7:

                (7) 0 9-18 * * 1-5:

                (8) */5 * * * *:每5分钟执行一次某任务;

                (9) */7

                

            crontab命令:

                crontab [-u user] [-l | -r | -e] [-i]

                    -e:编辑任务;

                    -l:列出所有任务;

                    -r:移除所有任务;即删除/var/spool/cron/USERNAME文件;

                    -i:在使用-r选项移除所有任务时提示用户确认;

                    -u user:root用户可为指定用户管理cron任务;                    

                                    

            注意:运行结果以邮件通知给当前用户;如果拒绝接收邮件:

                (1) COMMAND > /dev/null

                (2) COMMAND &> /dev/null

                

            注意:定义COMMAND时,如果命令需要用到%,需要对其转义;但放置于单引号中的%不用转义亦可;

            

            思考:某任务在指定的时间因关机未能执行,下次开机会不会自动执行?

                不会!.

                如果期望某时间因故未能按时执行,下次开机后无论是否到了相应时间点都要执行一次,可使用anacron实现;

                

            课外作业:anacron及其应用;

            

    练习:

        1、每12小时备份一次/etc目录至/backups目录中,保存文件 名称格式为“etc-yyyy-mm-dd-hh.tar.xz”

        2、每周2、4、7备份/var/log/secure文件至/logs目录中,文件名格式为“secure-yyyymmdd”;

        3、每两小时取出当前系统/proc/meminfo文件中以S或M开头的行信息追加至/tmp/meminfo.txt文件中;

        


Linux程序包管理

    

    概述

        API:Application Program Interface

        ABI:Application Binary Interface

            Unix-like,

                ELF

            Windows

                exe, msi

                    

            库级别的虚拟化:

                Linux: WinE

                Windows: Cywin

                

        系统级开发:

            C/C++:httpd, vsftpd, nginx

            go

        应用级开发:

            java/Python/perl/ruby/php:

                java: hadoop,  hbase,   (jvm)

                Python:openstack, (pvm)

                perl: (perl)

                ruby: (ruby)

                php: (php)

                

        C/C++程序格式:

            源代码:文本格式的程序代码;

                编译开发环境:编译器、头文件、开发库

            二进制格式:文本格式的程序代码 --> 编译器 --> 二进制格式(二进制程序、库文件、配置文件、帮助文件)

            

        java/python程序格式:

            源代码:编译成能够在其虚拟机(jvm/pvm)运行的格式;

                开发环境:编译器、开发库

            二进制

            

        项目构建工具:

            c/c++: make

            java: maven

            

    程序包管理器:

        源代码  --> 目标二进制格式(二进制程序、库文件、配置文件、帮助文件) --> 组织成为一个或有限几个“包”文件;

            安装、升级、卸载、查询、校验

            

        程序包管理器:

            debian:dpt, dpkg, ".deb"

            redhat:redhat package manager, rpm, ".rpm"; rpm is package manager;

            S.u.S.E:rpm, ".rpm",

            

            Gentoo:ports

            ArchLinux:

            

        源代码:name-VERSION.tar.gz

            VERSION:major.minor.release

        rpm包命名格式:

            name-VERSION-release.arch.rpm

                VERSION:major.minor.release

                release.arch:rpm包的发行号

                    release.os: 2.el7.i386.rpm

                    archetecture:i386, x64(amd64), ppc, noarch

                    

                redis-3.0.2.targz --> redis-3.0.2-1.centos7.x64.rpm

            

            拆包:主包和支包

                主包:name-VERSION-release.arch.rpm

                支包:name-function-VERSION-release.arch.rpm

                    function:devel, utils, libs, ...

                

        依赖关系:

            X, Y, Z

            

                X --> Y,Z

                    Y --> A, B, C

                    C --> Y

                    

            前端工具:自动解决依赖关系;

                yum:rhel系列系统上rpm包管理器的前端工具;

                apt-get (apt-cache):deb包管理器的前端工具;

                zypper:suse的rpm管理器前端工具;

                dnf:Fedora 22+系统上rpm包管理器的前端工具;

                

        程序包管理器:

            功能:将编译好的应用程序的各组成文件打包成一个或几个程序包文件,从而更方便地实现程序包的安装、升级、卸载和查询等管理操作;

            

            1、程序包的组成清单(每个程序包都单独实现);

                文件清单

                安装或卸载时运行的脚本

            2、数据库(公共)

                程序包的名称和版本;

                依赖关系;

                功能说明;

                安装生成的各文件的文件路径及校验码信息;

                等等等

                

                /var/lib/rpm/

                

    获取程序包的途径:

        (1) 系统发行版的光盘或官方的文件服务器(或镜像站点):

            http://mirrors.aliyun.com,

            http://mirrors.sohu.com,

            http://mirrors.163.com

        (2) 项目的官方站点

        (3) 第三方组织:

            (a) EPEL

            (b) 搜索引擎

                http://pkgs.org

                http://rpmfind.net

                http://rpm.pbone.net

        (4) 自动动手,丰衣足食

        

        建议:检查其合法性

            来源合法性;

            程序包的完整性;

            

    CentOS系统上rpm命令管理程序包:

        安装、升级、卸载、查询和校验、数据库维护

        

        rpm命令:rpm  [OPTIONS]  [PACKAGE_FILE]

            安装:-i, --install

            升级:-U, --update, -F, --freshen

            卸载:-e, --erase

            查询:-q, --query

            校验:-V, --verify

            数据库维护:--builddb, --initdb

            

        安装:

            rpm {-i|--install} [install-options] PACKAGE_FILE ...

            

                rpm  -ivh  PACKAGE_FILE ...

                

                GENERAL OPTIONS:

                    -v:verbose,详细信息

                    -vv:更详细的输出

                

                [install-options]:

                    -h:hash marks输出进度条;每个#表示2%的进度;

                    --test:测试安装,检查并报告依赖关系及冲突消息等;

                    --nodeps:忽略依赖关系;不建议;

                    --replacepkgs:重新安装

                    

                    注意:rpm可以自带脚本;

                        四类:--noscripts

                            preinstall:安装过程开始之前运行的脚本,%pre , --nopre

                            postinstall:安装过程完成之后运行的脚本,%post , --nopost

                            preuninstall:卸载过程真正开始执行之前运行的脚本,%preun, --nopreun

                            postuninstall:卸载过程完成之后运行的脚本,%postun , --nopostun

                            

                    --nosignature:不检查包签名信息,不检查来源合法性;

                    --nodigest:不检查包完整性信息;

                    

        升级:

            rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...

            rpm {-F|--freshen} [install-options] PACKAGE_FILE ...

            

                -U:升级或安装;

                -F:升级

                

                rpm  -Uvh PACKAGE_FILE ...

                rpm  -Fvh PACKAGE_FILE ...

                

                    --oldpackage:降级;

                    --force:强制升级;

                    

                注意:(1) 不要对内核做升级操作;Linux支持多内核版本并存,因此,直接安装新版本内核;

                        (2) 如果某原程序包的配置文件安装后曾被修改过,升级时,新版本的程序提供的同一个配置文件不会覆盖原有版本的配置文件,而是把新版本的配置文件重命名(FILENAME.rpmnew)后提供;

                        

        卸载:

            rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--test] PACKAGE_NAME ...

                

                --allmatches:卸载所有匹配指定名称的程序包的各版本;

                --nodeps:忽略依赖关系

                --test:测试卸载,dry run模式

                

        查询:

            rpm {-q|--query} [select-options] [query-options]

            

             [select-options]

                PACKAGE_NAME:查询指定的程序包是否已经安装,及其版本;

                -a, --all:查询所有已经安装过的包;

                -f  FILE:查询指定的文件由哪个程序包安装生成;

                

                -p, --package PACKAGE_FILE:用于实现对未安装的程序包执行查询操作;

                

                --whatprovides CAPABILITY:查询指定的CAPABILITY由哪个程序包提供;

                --whatrequires CAPABILITY:查询指定的CAPABILITY被哪个包所依赖;

                

            [query-options]

                --changelog:查询rpm包的changlog;

                -l, --list:程序安装生成的所有文件列表;

                -i, --info:程序包相关的信息,版本号、大小、所属的包组,等;

                -c, --configfiles:查询指定的程序包提供的配置文件;

                -d, --docfiles:查询指定的程序包提供的文档;

                --provides:列出指定的程序包提供的所有的CAPABILITY;

                -R, --requires:查询指定的程序包的依赖关系;

                --scripts:查看程序包自带的脚本片断;

                

            用法:

                -qi  PACKAGE, -qf FILE, -qc PACKAGE, -ql PACKAGE, -qd PACKAGE

                -qpi  PACKAGE_FILE, -qpl PACKAGE_FILE, -qpc PACKAGE_FILE, ...

                

        校验:

            rpm {-V|--verify} [select-options] [verify-options]    

                

                

            S file Size differs

            M Mode differs (includes permissions and file type)

            5 digest (formerly MD5 sum) differs

            D Device major/minor number mismatch

            L readLink(2) path mismatch

            U User ownership differs

            G Group ownership differs

            T mTime differs

            P caPabilities differ

            

    包来源合法性验正和完整性验正:

        来源合法性验正:

        完整性验正:

        

        获取并导入信任的包制作者的密钥:

            对于CentOS发行版来说:rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

            

        验正:

            (1) 安装此组织签名的程序时,会自动执行验正;

            (2) 手动验正:rpm -K PACKAGE_FILE

            

    数据库重建:

        rpm管理器数据库路径:/var/lib/rpm/

            查询操作:通过此处的数据库进行;

            

        获取帮助:

            CentOS 6:man rpm

            CentOS 7:man rpmdb

            

            rpm {--initdb|--rebuilddb} [--dbpath DIRECTORY] [--root DIRECTORY]

                --initdb:初始化数据库,当前无任何数据库可实始化创建一个新的;当前有时不执行任何操作;

                --rebuilddb:重新构建,通过读取当前系统上所有已经安装过的程序包进行重新创建;

            

        博客作业:rpm包管理功能全解;

    

    

回顾:Linux程序包管理的实现、rpm包管理器


    rpm命令实现程序管理:

        安装:-ivh, --nodeps, --replacepkgs

        卸载:-e, --nodeps

        升级:-Uvh, -Fvh, --nodeps, --oldpackage

        查询:-q, -qa, -qf, -qi, -qd, -qc, -q --scripts, -q --changlog, -q --provides, -q --requires

        校验:-V


        导入GPG密钥:--import, -K, --nodigest, --nosignature

        数据库重建:--initdb, --rebuilddb


Linux程序包管理(2)


    CentOS: yum, dnf


    URL: ftp://172.16.0.1/pub/    


    YUM: yellow dog, Yellowdog Update Modifier


    yum repository: yum repo

        存储了众多rpm包,以及包的相关的元数据文件(放置于特定目录下:repodata);


        文件服务器:

            ftp://

            http://

            nfs://

            file:///


    yum客户端:

        配置文件:

            /etc/yum.conf:为所有仓库提供公共配置

            /etc/yum.repos.d/*.repo:为仓库的指向提供配置


        仓库指向的定义:

        [repositoryID]

        name=Some name for this repository

        baseurl=url://path/to/repository/

        enabled={1|0}

        gpgcheck={1|0}

        gpgkey=URL

        enablegroups={1|0}

        failovermethod={roundrobin|priority}

            默认为:roundrobin,意为随机挑选;

        cost=

            默认为1000



        教室里的yum源:http://172.16.0.1/cobbler/ks_mirror/CentOS-6.6-x86_64/

        CentOS 6.6 X84_64 epel: http://172.16.0.1/fedora-epel/6/x86_64/


    yum命令的用法:

        yum [options] [command] [package ...]


       command is one of:

        * install package1 [package2] [...]

        * update [package1] [package2] [...]

        * update-to [package1] [package2] [...]

        * check-update

        * upgrade [package1] [package2] [...]

        * upgrade-to [package1] [package2] [...]

        * distribution-synchronization [package1] [package2] [...]

        * remove | erase package1 [package2] [...]

        * list [...]

        * info [...]

        * provides | whatprovides feature1 [feature2] [...]

        * clean [ packages | metadata | expire-cache | rpmdb | plugins | all ]

        * makecache

        * groupinstall group1 [group2] [...]

        * groupupdate group1 [group2] [...]

        * grouplist [hidden] [groupwildcard] [...]

        * groupremove group1 [group2] [...]

        * groupinfo group1 [...]

        * search string1 [string2] [...]

        * shell [filename]

        * resolvedep dep1 [dep2] [...]

        * localinstall rpmfile1 [rpmfile2] [...]

           (maintained for legacy reasons only - use install)

        * localupdate rpmfile1 [rpmfile2] [...]

           (maintained for legacy reasons only - use update)

        * reinstall package1 [package2] [...]

        * downgrade package1 [package2] [...]

        * deplist package1 [package2] [...]

        * repolist [all|enabled|disabled]

        * version [ all | installed | available | group-* | nogroups* | grouplist | groupinfo ]

        * history [info|list|packages-list|packages-info|summary|addon-info|redo|undo|rollback|new|sync|stats]

        * check

        * help [command]


    显示仓库列表:

        repolist [all|enabled|disabled]


    显示程序包:

        list

            # yum list [all | glob_exp1] [glob_exp2] [...]

            # yum list {available|installed|updates} [glob_exp1] [...]


    安装程序包:

        install package1 [package2] [...]


        reinstall package1 [package2] [...]  (重新安装)


    升级程序包:

        update [package1] [package2] [...]


        downgrade package1 [package2] [...] (降级)


    检查可用升级:

        check-update


    卸载程序包:

        remove | erase package1 [package2] [...]


    查看程序包information:

        info [...]


    查看指定的特性(可以是某文件)是由哪个程序包所提供:

        provides | whatprovides feature1 [feature2] [...]


    清理本地缓存:

        clean [ packages | metadata | expire-cache | rpmdb | plugins | all ]


    构建缓存:

        makecache


    搜索:

        search string1 [string2] [...]


        以指定的关键字搜索程序包名及summary信息;


    查看指定包所依赖的capabilities:

        deplist package1 [package2] [...]


    查看yum事务历史:

        history [info|list|packages-list|packages-info|summary|addon-info|redo|undo|rollback|new|sync|stats]


    安装及升级本地程序包:

        * localinstall rpmfile1 [rpmfile2] [...]

           (maintained for legacy reasons only - use install)

        * localupdate rpmfile1 [rpmfile2] [...]

           (maintained for legacy reasons only - use update)


    包组管理的相关命令:

        * groupinstall group1 [group2] [...]

        * groupupdate group1 [group2] [...]

        * grouplist [hidden] [groupwildcard] [...]

        * groupremove group1 [group2] [...]

        * groupinfo group1 [...]


    如何使用光盘当作本地yum仓库:

        (1) 挂载光盘至某目录,例如/media/cdrom

            # mount -r -t iso9660 /dev/cdrom /media/cdrom

        (2) 创建配置文件

        [CentOS7]

        name=

        baseurl=

        gpgcheck=

        enabled=


    yum的命令行选项:

        --nogpgcheck:禁止进行gpg check;

        -y: 自动回答为“yes”;

        -q:静默模式;

        --disablerepo=repoidglob:临时禁用此处指定的repo;

        --enablerepo=repoidglob:临时启用此处指定的repo;

        --noplugins:禁用所有插件;


    yum的repo配置文件中可用的变量:

        $releasever: 当前OS的发行版的主版本号;

        $arch: 平台;

        $basearch:基础平台;

        $YUM0-$YUM9


        http://mirrors.magedu.com/centos/$releasever/$basearch/os


    创建yum仓库:

        createrepo [options] <directory>


    程序包编译安装:

        testapp-VERSION-release.src.rpm --> 安装后,使用rpmbuild命令制作成二进制格式的rpm包,而后再安装;


        源代码 --> 预处理 --> 编译(gcc) --> 汇编 --> 链接 --> 执行


        源代码组织格式:

            多文件:文件中的代码之间,很可能存在跨文件依赖关系;


            C、C++: make (configure --> Makefile.in --> makefile)

            java: maven



            C代码编译安装三步骤:

                ./configure:

                    (1) 通过选项传递参数,指定启用特性、安装路径等;执行时会参考用户的指定以及Makefile.in文件生成makefile;

                    (2) 检查依赖到的外部环境;

                make:

                    根据makefile文件,构建应用程序;

                make install


            开发工具:

                autoconf: 生成configure脚本

                automake:生成Makefile.in


            建议:安装前查看INSTALL,README


        开源程序源代码的获取:

            官方自建站点:

                apache.org (ASF)

                mariadb.org

                ...

            代码托管:

                SourceForge

                Github.com

                code.google.com


        c/c++: gcc (GNU C Complier)


        编译C源代码:

            前提:提供开发工具及开发环境

                开发工具:make, gcc等

                开发环境:开发库,头文件

                    glibc:标准库


                通过“包组”提供开发组件

                    CentOS 6: "Development Tools", "Server Platform Development",


            第一步:configure脚本

                选项:指定安装位置、指定启用的特性


                --help: 获取其支持使用的选项

                    选项分类:

                        安装路径设定:

                            --prefix=/PATH/TO/SOMEWHERE: 指定默认安装位置;默认为/usr/local/

                            --sysconfdir=/PATH/TO/SOMEWHERE:配置文件安装位置;


                        System types:


                        Optional Features: 可选特性

                            --disable-FEATURE

                            --enable-FEATURE[=ARG]


                        Optional Packages: 可选包

                            --with-PACKAGE[=ARG]

                            --without-PACKAGE


            第二步:make


            第三步:make install


        安装后的配置:

            (1) 导出二进制程序目录至PATH环境变量中;

                编辑文件/etc/profile.d/NAME.sh

                    export PATH=/PATH/TO/BIN:$PATH


            (2) 导出库文件路径

                编辑/etc/ld.so.conf.d/NAME.conf

                    添加新的库文件所在目录至此文件中;


                让系统重新生成缓存:

                    ldconfig [-v]


            (3) 导出头文件

                基于链接的方式实现:

                    ln -sv


            (4) 导出帮助手册

                编辑/etc/man.config文件

                    添加一个MANPATH


    练习:

        1、yum的配置和使用;包括yum repository的创建;

        2、编译安装apache 2.2; 启动此服务;


    博客作业:程序包管理:rpm/yum/编译                

                

桌面环境:

    Windows 7, OpenSUSE 13.2,  Kubuntu(KDE)

    

回顾:yum 程序包管理器和编译安装


    C/S:

        yum client (yum)

        yum repository (ftp/http/https)

        

    base:

    extras

    updates

    

        

    repo:

        [id]

        name=

        baseurl=http://

            http://

            

    教室环境中的可用仓库:

        CentOS 6.7:

            http://172.16.0.1/cobbler/ks_mirror/CentOS-6.7-x86_64/

        CentOS 7.1:

            http://172.16.0.1/cobbler/ks_mirror/CentOS-7-x86_64-1503/

            

    子命令:

        list, clean, makecache, grouplist, info, whatprovides

        install, update, remove, groupinstall, groupupdate, groupremove, groupinfo

        

        rpm -ivh  /usr/local/src/testapp-3.2.1-1.el7.x86_64.rpm

            file:///

            

    编译安装:

        C/C++:

            ./configure --> Makefile.in ==> makefile

                make + makefile ==> binary, library, configfile, manual

                make install

            

        perl, Python, Java

        

bash脚本编程

    

    过程式编程语言的执行流程:

        顺序执行

        选择执行

        循环执行

        

    选择执行:

        (1) &&, ||

        (2) if语句

        (3) case语句

        

        if语句:三种格式

            单分支的if语句

                if  CONDITION; then

                    if-true-分支;

                fi

                

            双分支的if语句

                if  CONDITION; then

                    if-true-分支

                else

                    if-false-分支

                fi

                

            多分支的if语句

                if  CONDITION1; then

                    条件1为真分支

                elif  CONDITION2; then

                    条件2为真分支

                elif  CONDITION3; then

                    条件3为真分支

                ...

                elif  CONDITIONn; then

                    条件n为真分支

                else

                    所有条件均不满足时的分支

                fi

                

                注意:即便多个条件可能同时都能满足,分支只会执行中其中一个,首先测试为“真”;

                

                示例:脚本参数传递一个文件路径给脚本,判断此文件的类型;

                    

                    #!/bin/bash

                    #

                    if [ $# -lt 1 ]; then

                        echo "At least on path."

                        exit 1

                    fi


                    if ! [ -e $1 ]; then

                        echo "No such file."

                        exit 2

                    fi


                    if [ -f $1 ]; then

                        echo "Common file."

                    elif [ -d $1 ]; then

                        echo "Directory."

                    elif [ -L $1 ]; then

                        echo "Symbolic link."

                    elif [ -b $1 ]; then

                        echo "block special file."

                    elif [ -c $1 ]; then

                        echo "character special file."

                    elif [ -S $1 ]; then

                        echo "Socket file."

                    else

                        echo "Unkown."

                    fi    

                    

                    注意:if语句可嵌套;

                    

            练习:写一个脚本

                (1) 传递一个参数给脚本,此参数为用户名;

                (2) 根据其ID号来判断用户类型:

                    0: 管理员

                    1-999:系统用户

                    1000+:登录用户

                    

                    #!/bin/bash

                    #

                    [ $# -lt 1 ] && echo "At least on user name." && exit 1


                    ! id $1 &> /dev/null && echo "No such user." && exit 2


                    userid=$(id -u $1)


                    if [ $userid -eq 0 ]; then

                        echo "root"

                    elif [ $userid -ge 1000 ]; then

                        echo "login user."

                    else

                        echo "System user."

                    fi                                        

                    

            练习:写一个脚本

                (1) 列出如下菜单给用户:

                    disk) show disks info;

                    mem) show memory info;

                    cpu) show cpu info;

                    *) quit;

                (2) 提示用户给出自己的选择,而后显示对应其选择的相应系统信息;

                

                    #!/bin/bash

                    #

                    cat << EOF

                    disk) show disks info

                    mem) show memory info

                    cpu) show cpu info

                    *) QUIT

                    EOF


                    read -p "Your choice: " option


                    if [[ "$option" == "disk" ]]; then

                        fdisk -l /dev/[sh]d[a-z]

                    elif [[ "$option" == "mem" ]]; then

                        free -m

                    elif [[ "$option" == "cpu" ]];then

                        lscpu

                    else

                        echo "Unkown option."

                        exit 3

                    fi

                    

    循环执行: 将一段代码重复执行0、1或多次;

        进入条件:条件满足时才进入循环;

        退出条件:每个循环都应该有退出条件,以有机会退出循环;

        

        bash脚本:

            for循环

            while循环

            until循环

            

        for循环:

            两种格式:

                (1) 遍历列表

                (2) 控制变量

                

            遍历列表:

                for  VARAIBLE  in  LIST; do

                    循环体

                done

                

                进入条件:只要列表有元素,即可进入循环;

                退出条件:列表中的元素遍历完成;

                

                LISTT的生成方式:

                    (1) 直接给出;

                    (2) 整数列表

                        (a) {start..end}

                        (b) seq [start  [incremtal]] last

                    (3) 返回列表的命令

                    (4) glob

                    (5) 变量引用

                        $@, $*

                    ...

                

                #!/bin/bash

                #

                for username in user21 user22 user23; do

                    if id $username &> /dev/null; then

                        echo "$username exists."

                    else

                        useradd $username && echo "Add user $username finished."

                    fi

                done

                

                示例:求100以内所有正整数之和;

                    #!/bin/bash

                    #

                    declare -i sum=0


                    for i in {1..100}; do

                        echo "\$sum is $sum, \$i is $i"

                        sum=$[$sum+$i]

                    done


                    echo $sum

        

                示例:判断/var/log目录下的每一个文件的内容类型

                    #!/bin/bash

                    #

                    for filename in /var/log/*; do

                        if [ -f $filename ]; then

                            echo "Common file."

                        elif [ -d $filename ]; then

                            echo "Directory."

                        elif [ -L $filename ]; then

                            echo "Symbolic link."

                        elif [ -b $filename ]; then

                            echo "block special file."

                        elif [ -c $filename ]; then

                            echo "character special file."

                        elif [ -S $filename ]; then

                            echo "Socket file."

                        else

                            echo "Unkown."

                        fi                    

                    done

                    

                练习:

                    1、分别求100以内所有偶数之和,以及所有奇数之和;

                    2、计算当前系统上的所有用的id之和;

                    3、通过脚本参数传递一个目录给脚本,而后计算此目录下所有文本文件的行数之和;并说明此类文件的总数;

                    

sed命令:

    

    文本处理三剑客:

        grep, egrep, fgrep:文本过滤器

        sed:Stream EDitor,流编辑器,行

        awk:文本格式化工具,报告生成器

        

    sed [OPTION]...  'script'  [input-file] ...

        script:

            地址定界编辑命令

            

        常用选项:

            -n:不输出模式空间中的内容至屏幕;

            -e script, --expression=script:多点编辑;

            -f  /PATH/TO/SED_SCRIPT_FILE

                每行一个编辑命令;

            -r, --regexp-extended:支持使用扩展正则表达式;

            -i[SUFFIX], --in-place[=SUFFIX]:直接编辑原文件 ;

        

            ~]# sed  -e  's@^#[[:space:]]*@@'   -e  '/^UUID/d'  /etc/fstab

        

        地址定界:

            (1) 空地址:对全文进行处理;

            (2) 单地址:

                #:指定行;

                /pattern/:被此模式所匹配到的每一行;

            (3) 地址范围

                #,#:

                #,+#:

                #,/pat1/

                /pat1/,/pat2/

                $:最后一行;

            (4) 步进:~

                1~2:所有奇数行

                2~2:所有偶数行

                

        编辑命令:

            d:删除;

            p:显示模式空间中的内容;

            a  \text:在行后面追加文本“text”,支持使用\n实现多行追加;

            i  \text:在行前面插入文本“text”,支持使用\n实现多行插入;

            c  \text:把匹配到的行替换为此处指定的文本“text”;

            w /PATH/TO/SOMEFILE:保存模式空间匹配到的行至指定的文件中;

            r  /PATH/FROM/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行后面;文件合并;

            =:为模式匹配到的行打印行号;

            !:条件取反;

                地址定界!编辑命令;

            s///:查找替换,其分隔符可自行指定,常用的有s@@@, s###等;

                替换标记:

                    g:全局替换;

                    w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中;

                    p:显示替换成功的行;

                

                练习1:删除/boot/grub/grub2.cfg文件中所有以空白字符开头的行的行首的所有空白字符;

                    ~]# sed  's@^[[:space:]]\+@@' /etc/grub2.cfg

                练习2:删除/etc/fstab文件中所有以#开头的行的行首的#号及#后面的所有空白字符;

                    ~]# sed  's@^#[[:space:]]*@@'  /etc/fstab

                练习3:输出一个绝对路径给sed命令,取出其目录,其行为类似于dirname;

                    ~]# echo "/var/log/messages/" | sed 's@[^/]\+/\?$@@'

                    ~]# echo "/var/log/messages" | sed -r 's@[^/]+/?$@@'

                    

        高级编辑命令:

            h:把模式空间中的内容覆盖至保持空间中;

            H:把模式空间中的内容追加至保持空间中;

            g:把保持空间中的内容覆盖至模式空间中;

            G:把保持空间中的内容追加至模式空间中;

            x:把模式空间中的内容与保持空间中的内容互换;

            n:覆盖读取匹配到的行的下一行至模式空间中;

            N:追加读取匹配到的行的下一行至模式空间中;

            d:删除模式空间中的行;

            D:删除多行模式空间中的所有行;

            

            示例:

                sed  -n  'n;p'  FILE:显示偶数行;

                sed  '1!G;h;$!d'  FILE:逆序显示文件的内容;

                sed  ’$!d'  FILE:取出最后一行;

                sed  '$!N;$!D' FILE:取出文件后两行;

                sed '/^$/d;G' FILE:删除原有的所有空白行,而后为所有的非空白行后添加一个空白行;

                sed  'n;d'  FILE:显示奇数行;

                sed 'G' FILE:在原有的每行后方添加一个空白行;

                

        博客作业:sed的用法;

            

Linux网络属性配置                

        

    计算机网络:    

        TCP/IP:协议栈(使用)

            ISO,OSI:协议栈(学习)

            

        MAC:Media Access Control

            48bits:

                ICANN:24bits, 2^24

                    地址块:2^24

                    

                网桥(bridge):MAC地址表

                    静态指定:

                    动态学习:根据原地址学习;

                    

                交换机(switch):多端口网桥;    

                    

        IP(Internet protocol)地址:网络号+主机号

                A<-->B

                    网络?

                    主机?

                

                IPv4:32bits

                    8bits.8bits.8bits.8bits

                        0-255

                        0.0.0.0-255.255.255.255

                        

                    IP地址分类:

                        A类:

                            第一段为网络号,后三段为主机号

                            网络号:

                                0 000 0000 - 0 111 1111:1-127

                            网络数量:126,127

                            每个网络中的主机数量:2^24-2

                            默认子网掩码:255.0.0.0,/8

                                用于与IP地址按位进行“与”运算,从而取出其网络地址;

                                    1.3.2.1/255.0.0.0 = 1.0.0.0

                                    1.3.2.1/255.255.0.0= 1.3.0.0    

                            私网地址:10.0.0.0/255.0.0.0

                        B类:

                            前两段为网络号,后两段为主机号

                            网络号:

                                10 00 0000 - 10 11 1111:128-191

                                网络数:2^14

                                每个网络中的主机数量:2^16-2

                                默认子网掩码:255.255.0.0,/16

                                私网地址:172.16.0.0-172.31.0.0                                

                        C类:

                            前三段为网络号,最后一段为主机号

                            网络号:

                                110 0 0000 - 110 1 1111:192-223

                            网络数:2^21

                            每个网络中的主机数量:2^8-2

                            默认子网掩码:255.255.255.0,  /24

                        D类:组播

                            1110 0000 - 1110 1111:224-239

                        E类:科研

                            240-255

                IPv6:128bits

                

                    路由器:router

                        路由表:

                            静态指定

                            动态学习:rip2, ospf

                            

                        路由条目:

                            目标地址  下一跳(nexthop)

                                目标地址的类别:

                                    主机:主机路由

                                    网络:网络路由

                                    0.0.0.0/0.0.0.0:默认路由                            

    OS:多用户,多任务

        多任务:多进程

            chrome:

            QQ:

            QQ Music:

            

        通信时,进程的数字标识:

            16bits:

                0-65535:1-65535

                    1-1023:固定分配,而且只有管理员有权限启用;

                    1024-4W:半固定,

                    4W+:临时;

        进程地址:

            IP:PORT,  socket

            

    总结:

        MAC:本地通信;范围:本地局域网;

        IP:界定通信主机,源和目标;范围:互联网;

        Port:界定进程;范围:主机 ;

        

    将Linux主机接入到网络中:

        IP/NETMASK:本地通信

        路由(网关):跨网络通信

        DNS服务器地址:基于主机名的通信

            主DNS服务器地址

            备用DNS服务器地址

            第三备份DNS服务器地址

            

        配置方式:

            静态指定:

                命令:

                    ifcfg家族:

                        ifconfig:配置IP,NETMASK

                        route:路由

                        netstat:状态及统计数据查看

                    iproute2家族:

                        ip OBJECT:

                            addr:地址和掩码;

                            link:接口

                            route:路由

                        ss:状态及统计数据查看

                    CentOS 7:nm(Network Manager)家族

                        nmcli:命令行工具

                        nmtui:text window 工具

                        

                    注意:

                        (1) DNS服务器指定    

                            配置文件:/etc/resolv.conf

                        (2) 本地主机名配置

                            hostname

                            配置文件:/etc/sysconfig/network

                            CentOS 7:hostnamectl                    

                配置文件:

                    RedHat及相关发行版

                        /etc/sysconfig/network-scripts/ifcfg-NETCARD_NAME

                    

            动态分配:依赖于本地网络中有DHCP服务

                DHCP:Dynamic Host Configure Procotol

                

    网络接口命名方式:

        传统命名:

            以太网:ethX, [0,oo),例如eth0, eth1, ...

            PPP网络:pppX, [0,...], 例如,ppp0, ppp1, ...

        

        可预测命名方案(CentOS):

            支持多种不同的命名机制:

                Fireware, 拓扑结构

                

            (1) 如果Firmware或BIOS为主板上集成的设备提供的索引信息可用,则根据此索引进行命名,如eno1, eno2, ...

            (2) 如果Firmware或BIOS为PCI-E扩展槽所提供的索引信息可用,且可预测,则根据此索引进行命名,如ens1, ens2, ...

            (3) 如果硬件接口的物理位置信息可用,则根据此信息命名,如enp2s0, ...

            (4) 如果用户显式定义,也可根据MAC地址命名,例如enx122161ab2e10, ...

            上述均不可用,则仍使用传统方式命名;

            

            命名格式的组成:

                en:ethernet

                wl:wlan

                ww:wwan

                

                名称类型:

                    o<index>:集成设备的设备索引号;

                    s<slot>:扩展槽的索引号;

                    x<MAC>:基于MAC地址的命名;

                    p<bus>s<slot>:基于总线及槽的拓扑结构进行命名;

                    

回顾:计算机网络基础、Linux网络属性配置

    TCP/IP协议栈:物理层、互联网层、传输层、应用层

        互联网层:IP

        传输层:TCP, UDP

        应用层:http, https, ftp, ldap, ...

        

    链接路层:以太网帧

    互联网层:IP报文

    

    以太网帧:MTU(1500)

        

    Linux网络属性配置:命令,配置文件;

        

Linux网络属性配置(2)


    ifcfg命令家族: ifconfig, route, netstat

        

        ifconfig命令:接口及地址查看和管理

            ifconfig  [INTERFACE]

                # ifconfig -a:显示所有接口,包括inactive状态的接口;

            

            ifconfig interface [aftype] options | address ...

                # ifconfig  IFACE  IP/MASK  [up|down]

                # ifconfig  IFACE  IP  netmask  NETMASK  

                

                options:

                    [-]promisc

                

                注意:立即送往内核中的TCP/IP协议栈,并生效;

                

            管理IPv6地址:

                add addr/prefixlen

                del  addr/prefixlen

                

        route命令:路由查看及管理

        

            路由条目类型:

                主机路由:目标地址为单个IP;

                网络路由:目标地址为IP网络;

                默认路由:目标为任意网络,0.0.0.0/0.0.0.0

                

            查看:

                # route  -n

            添加:

                route  add  [-net|-host]  target  [netmask  Nm]  [gw GW]  [[dev] If]

                

                    示例:route add -net  10.0.0.0/8  gw  192.168.10.1  dev  eth1

                                route add  -net  0.0.0.0/0.0.0.0  gw 192.168.10.1  

                                route add  default  gw 192.168.10.1  

                                

            删除:

                route  del  [-net|-host] target  [gw Gw]  [netmask Nm]  [[dev] If]

                    

                    示例: route  del  -net  10.0.0.0/8  gw 192.168.10.1

                             route  del  default

                             

        netstat命令:

            Print network connections, routing tables, interface statistics, masquerade connections, and multicast  memberships

            

            显示路由表:netstat  -rn

                -r:显示内核路由表

                -n:数字格式

                

            显示网络连接:

                netstat  [--tcp|-t]  [--udp|-u]  [--udplite|-U]  [--sctp|-S]  [--raw|-w]  [--listening|-l]  [--all|-a]  [--numeric|-n]   [--extend|-e[--extend|-e]]  [--program|-p]

                    -t:TCP协议的相关连接,连接均有其状态;FSM(Finate State Machine);

                    -u:UDP相关的连接

                    -w:raw socket相关的连接

                    -l:处于监听状态的连接

                    -a:所有状态

                    -n:以数字格式显示IP和Port;

                    -e:扩展格式

                    -p:显示相关的进程及PID;

                    

                常用组合:

                    -tan,  -uan,  -tnl,  -unl,  -tunlp

                                

                传输层协议:

                    tcp:面向连接的协议;通信开始之前,要建立一个虚链路;通信完成后还要拆除连接;

                    udp:无连接的协议;直接发送数据报文;

                    

            显示接口的统计数据:

                netstat    {--interfaces|-I|-i}    [iface]   [--all|-a]   [--extend|-e]   [--verbose|-v]   [--program|-p]  [--numeric|-n]

                    

                所有接口:

                    netstat  -i

                指定接口:

                    netstat  -I<IFace>

                    

        ifup/ifdown命令:

            注意:通过配置文件/etc/sysconfig/network-scripts/ifcfg-IFACE来识别接口并完成配置;

    

    配置主机名:

    

        hostname命令:

            查看:hostname

            配置:hostname  HOSTNAME

                当前系统有效,重启后无效;

            

        hostnamectl命令(CentOS 7):

            hostnamectl  status:显示当前主机名信息;

            hostnamectl  set-hostname:设定主机名,永久有效;

            

        配置文件:/etc/sysconfig/network

            HOSTNAME=<HOSTNAME>

            

            注意:此方法的设置不会立即生效; 但以后会一直有效;

            

    配置DNS服务器指向:

        

        配置文件:/etc/resolv.conf

            nameserver   DNS_SERVER_IP

            

            如何测试(host/nslookup/dig):

                # dig  -t  A  FQDN

                    FQDN --> IP

                    

                # dig  -x  IP

                    IP --> FQDN

                    

    iproute家族:

        ip命令:

            show / manipulate routing, devices, policy routing and tunnels

            

            ip [ OPTIONS ] OBJECT { COMMAND | help }

                OBJECT := { link | addr | route | netns  }

            

            注意: OBJECT可简写,各OBJECT的子命令也可简写;

                

            ip  OBJECT:

                

                ip link: network device configuration

                

                    ip  link  set - change device attributes

                        dev NAME (default):指明要管理的设备,dev关键字可省略;

                        up和down:

                        multicast on或multicast off:启用或禁用多播功能;

                        name NAME:重命名接口

                        mtu NUMBER:设置MTU的大小,默认为1500;

                        netns PID:ns为namespace,用于将接口移动到指定的网络名称空间;

                        

                    ip  link  show  - display device attributes

                    

                    ip  link  help -  显示简要使用帮助;

                    

                ip netns:  - manage network namespaces.

                

                    ip  netns  list:列出所有的netns

                    ip  netns  add  NAME:创建指定的netns

                    ip  netns  del  NAME:删除指定的netns

                    ip  netns   exec  NAME  COMMAND:在指定的netns中运行命令

                    

                ip address - protocol address management.

                    

                    ip address add - add new protocol address

                        ip  addr  add  IFADDR  dev  IFACE

                            [label NAME]:为额外添加的地址指明接口别名;

                            [broadcast ADDRESS]:广播地址;会根据IP和NETMASK自动计算得到;

                            [scope SCOPE_VALUE]:

                                global:全局可用;

                                link:接口可用;

                                host:仅本机可用;                                                

                        

                    ip address delete - delete protocol address

                        ip addr  delete  IFADDR  dev  IFACE

                            

                    ip address show - look at protocol addresses

                        ip  addr   list  [IFACE]:显示接口的地址;

                        

                    ip address flush - flush protocol addresses

                        ip  addr  flush  dev  IFACE

                        

                ip route - routing table management

                

                    ip route add - add new route

                    ip route change - change route

                    ip route replace - change or add new one

                        ip  route   add  TYPE PREFIX  via GW  [dev  IFACE]  [src SOURCE_IP]

                        

                        示例:

                            # ip route add 192.168.0.0/24  via 10.0.0.1  dev eth1 src  10.0.20.100

                            # ip  route  add default  via  GW                        

                        

                    ip route delete - delete route

                        ip  route  del  TYPE PRIFIX

                        

                        示例:

                            # ip  route delete  192.168.1.0/24

                            

                    ip route show - list routes

                        TYPE PRIFIX  

                    ip route flush - flush routing tables

                        TYPE  PRIFIX

                    

                    ip route get - get a single route

                        ip  route  get  TYPE PRIFIX

                        

                        示例:ip route  get  192.168.0.0/24

                    

        ss命令:

            ss  [options]  [ FILTER ]

                选项:

                    -t:TCP协议的相关连接

                    -u:UDP相关的连接

                    -w:raw socket相关的连接

                    -l:监听状态的连接

                    -a:所有状态的连接

                    -n:数字格式

                    -p:相关的程序及其PID

                    -e:扩展格式信息

                    -m:内存用量

                    -o:计时器信息

                    

                FILTER := [ state TCP-STATE ]  [ EXPRESSION ]

                

                    TCP的常见状态:

                        TCP FSM:

                            LISTEN:监听

                            ESTABLISEHD:建立的连接

                            FIN_WAIT_1:

                            FIN_WAIT_2:

                            SYN_SENT:

                            SYN_RECV:

                            CLOSED:

                        

                    EXPRESSION:

                        dport =

                        sport =

                            示例:'( dport = :22 or sport = :22)'

                                ~]# ss   -tan    '(  dport = :22 or sport = :22  )'

                                ~]# ss  -tan  state  ESTABLISHED

                                

    配置文件:

        IP/NETMASK/GW/DNS等属性的配置文件:/etc/sysconfig/network-scripts/ifcfg-IFACE

            IFACE:接口名称;

        路由的相关配置文件:/etc/sysconfig/networkj-scripts/route-IFACE

                    

        配置文件/etc/sysconfig/network-scripts/ifcfg-IFACE通过大量参数来定义接口的属性;其可通过vim等文本编辑器直接修改,也可以使用专用的命令的进行修改(CentOS 6:system-config-network (setup),CentOS 7: nmtui)

        

            ifcfg-IFACE配置文件参数:

                DEVICE:此配置文件对应的设备的名称;

                ONBOOT:在系统引导过程中,是否激活此接口;

                UUID:此设备的惟一标识;

                IPV6INIT:是否初始化IPv6;

                BOOTPROTO:激活此接口时使用什么协议来配置接口属性,常用的有dhcp、bootp、static、none;

                TYPE:接口类型,常见的有Ethernet, Bridge;

                DNS1:第一DNS服务器指向;

                DNS2:备用DNS服务器指向;

                DOMAIN:DNS搜索域;

                IPADDR: IP地址;

                NETMASK:子网掩码;CentOS 7支持使用PREFIX以长度方式指明子网掩码;

                GATEWAY:默认网关;

                USERCTL:是否允许普通用户控制此设备;

                PEERDNS:如果BOOTPROTO的值为“dhcp”,是否允许dhcp server分配的dns服务器指向覆盖本地手动指定的DNS服务器指向;默认为允许;

                HWADDR:设备的MAC地址;

                

                NM_CONTROLLED:是否使用NetworkManager服务来控制接口;

                

            网络服务:

                network

                NetworkManager

                

                管理网络服务:

                    CentOS 6:  service  SERVICE  {start|stop|restart|status}

                    CentOS 7:systemctl  {start|stop|restart|status}  SERVICE[.service]

                    

                配置文件修改之后,如果要生效,需要重启网络服务;

                    CentOS 6:# service  network  restart

                    CentOS 7:# systemctl  restart  network.service

                    

        用到非默认网关路由:/etc/sysconfig/network-scripts/route-IFACE

            支持两种配置方式,但不可混用;

                (1) 每行一个路由条目:

                    TARGET  via  GW

                    

                (2) 每三行一个路由条目:

                    ADDRESS#=TARGET

                    NETMASK#=MASK

                    GATEWAY#=NEXTHOP

                    

    给接口配置多个地址:

        ip addr之外,ifconfig或配置文件都可以;

        

        (1) ifconfig  IFACE_LABEL  IPADDR/NETMASK

        

            IFACE_LABEL: eth0:0, eth0:1, ...

            

        (2) 为别名添加配置文件;

            DEVICE=IFACE_LABEL

            BOOTPROTO:网上别名不支持动态获取地址;

                static, none

                

    nmcli命令:

        nmcli  [ OPTIONS ] OBJECT { COMMAND | help }

            

            device - show and manage network interfaces

                COMMAND := { status | show | connect | disconnect | delete | wifi | wimax }

            

            connection - start, stop, and manage network connections

                COMMAND := { show | up | down | add | edit | modify | delete | reload | load }

                

                modify [ id | uuid | path ] <ID> [+|-]<setting>.<property> <value>

                

                如何修改IP地址等属性:

                    # nmcli  conn  modify  IFACE  [+|-]setting.property  value

                        ipv4.address

                        ipv4.gateway

                        ipv4.dns1

                        ipv4.method

                            manual

                            

    博客作业:上述所有内容;

        ifcfg, ip/ss,配置文件

        

    课外作业:nmap, ncat, tcpdump命令;

    


        

            

回顾:ip命令,ss命令;配置文件;CentOS 7


    ifcfg、ip、netstat、ss

    配置文件:

        /etc/sysconfig/network-scripts/

            ifcfg-IFNAME

            route-IFNAME

    CentOS 7: nmcli, nmtui


Linux进程及作业管理


    内核的功用:进程管理、文件系统、网络功能、内存管理、驱动程序、安全功能


    Process: 运行中的程序的一个副本;

        存在生命周期


    Linux内核存储进程信息的固定格式:task struct

        多个任务的的task struct组件的链表:task list


    进程创建:

        init

            父子关系

            进程:都由其父进程创建

                fork(), clone()


        进程优先级:

            0-139:

                1-99:实时优先级;

                100-139:静态优先级;

                    数字越小,优先级越高;


                Nice值:

                    -20,19


            Big O

                O(1), O(logn), O(n), O(n^2), O(2^n)


        进程内存:

            Page Frame: 页框,用存储页面数据

                存储Page


                MMU:Memory Management Unit


        IPC: Inter Process Communication

            同一主机上:

                signal

                shm: shared memory

                semerphor


            不同主机上:

                rpc: remote procecure call

                socket:


    Linux内核:抢占式多任务


        进程类型:

            守护进程: 在系统引导过程中启动的进程,跟终端无关的进程;

            前台进程:跟终端相关,通过终端启动的进程

                注意:也可把在前台启动的进程送往后台,以守护模式运行;


        进程状态:

            运行态:running

            就绪态:ready

            睡眠态:

                可中断:interruptable

                不可中断:uninterruptable

            停止态:暂停于内存中,但不会被调度,除非手动启动之;stopped

            僵死态:zombie


        进程的分类:

            CPU-Bound

            IO-Bound


        《Linux内核设计与实现》,《深入理解Linux内核》                    

            

    Linux系统上的进程查看及管理工具:pstree, ps, pidof, pgrep, top, htop, glances, pmap, vmstat, dstat, kill, pkill, job, bg, fg, nohup, nice, renice, killall, ...

        

        CentOS 5:  SysV init

        CentOS 6:upstart

        CentOS 7:systemd

        

            /sbin/init,

        

        pstree命令:

            pstree  - display a tree of processes

            

        ps命令:

            /proc/:内核中的状态信息;

                内核参数:

                    可设置其值从而调整内核运行特性的参数;/proc/sys/

                    状态变量:其用于输出内核中统计信息或状态信息,仅用于查看;

                    

                参数:模拟成文件系统类型;

                

            进程:

                /proc/#:

                    #:PID

                

            ps - report a snapshot of the current processes.

            

                ps [options]:

                    选项有三种风格:

                        1   UNIX options, which may be grouped and must be preceded by a dash.

                        2   BSD options, which may be grouped and must not be used with a dash.

                        3   GNU long options, which are preceded by two dashes.

                    

                    启动进程的方式:

                        系统启动过程中自动启动:与终端无关的进程;

                        用户通过终端启动:与终端相关的进程;

                        

                    选项:

                        a:所有与终端相关的进程;

                        x:所有与终端无关的进程;

                        u:以用户为中心组织进程状态信息显示;

                        

                        常用组合之一:aux

                            VSZ:虚拟内存集;

                            RSS:Resident Size,常驻内存集;

                            STAT:

                                R:running

                                S:interruptable sleeping

                                D:uninterruptable sleeping

                                T:Stopped

                                Z:zombie

                                

                                +:前台进程

                                l:多线程进程

                                N:低优先级进程

                                <:高优先级进程

                                s:session leader

                                

                        -e:显示所有进程

                        -f:显示完整格式的进程信息

                        

                        常用组合之二:-ef

                        

                        -F:显示完整格式的进程信息;

                            C: cpu utilization

                            PSR:运行于哪颗CPU之上

                        -H:以层级结构显示进程的相关信息;

                        

                        常用组合之三:-eFH

                        

                        常用组合之四:-eo, axo

                            o  field1, field2,...:自定义要显示的字段列表,以逗号分隔;

                                常用的field:pid, ni, pri, psr, pcpu, stat, comm, tty, ppid, rtprio

                                    ni:nice值;

                                    priority:priority, 优先级;

                                    rtprio:real time priority,实时优先级;

                                    

            pgrep, pkill命令:

                - look up or signal processes based on name and other attributes

                

                pgrep [options] pattern

                    -u uid:effective user

                    -U uid:read user

                    -t  TERMINAL:与指定的终端相关的进程;

                    -l:显示进程名;

                    -a:显示完整格式的进程名;

                    -P pid:显示此进程的子进程;

                    

            pidof命令:

                根据进程名,取其pid;

                

            top命令:

                - display Linux processes

                

                排序:

                    P:以占据CPU百分比排序;

                    M:以占据内存百分比排序;

                    T:累积占用CPU时间排序;

                    

                首部信息:

                    uptime信息:l命令

                    tasks及cpu信息:t命令

                    内存信息:m命令

                    

                退出命令:q

                修改刷新时间间隔:s

                终止指定的进程:k

                

                选项:

                    -d #:指定刷新时间间隔,默认为3秒;

                    -b:以批次方式显示;

                    -n #:显示多少批次;

                

            uptime命令:显示系统时间、运行时长及平均负载;

                过去1分钟、5分钟和15分钟的平均负载;

                    等待运行的进程队列的长度;

                    

回顾: Linux OS基础概念、进程查看的几工具;


    内核的功能:进程管理(进程调度)

        进程调度:保存现场,恢复现场;

            task struct:任务结构;

            task list:任务列表;

        

        CPU:us, sy, ni, id, hi, si, cs, st

        Memory:VSZ,RSS,SHM

        

    命令: pstree, pgrep, pkill, ps, top, uptime

    

Linux进程及作业管理(2)


    CentOS 6: http://172.16.0.1/fedora-epel/

    CentOS 7: http://172.16.0.1/fedora-epel/

    

    进程管理类命令:

    

        htop命令:

            选项:

                -d #:指定延迟时间间隔;

                -u UserName:仅显示指定用户的进程;

                -s COLUME:以指定字段进行排序;

            子命令:

                l:显示选定的进程打开的文件列表;

                s:跟踪选定的进程的系统调用;

                t:以层级关系显示各进程状态;

                a:将选定的进程绑定至某指定的CPU核心;

                

        vmstat命令:

            - Report virtual memory statistics

            

            vmstat  [options]  [delay [count]]

                procs:

                    r:等待运行的进程的个数;CPU上等待运行的任务的队列长度;

                    b:处于不可中断睡眠态的进程个数;被阻塞的任务队列的长度;

                memory:

                    swpd:交换内存使用总量;

                    free:空闲的物理内存总量;

                    buffer:用于buffer的内存总量;

                    cache:用于cache的内存总量;

                swap

                    si:数据进入swap中的数据速率(kb/s)

                    so:数据离开swap的速率(kb/s)

                io

                    bi:从块设备读入数据到系统的速度(kb/s)

                    bo:保存数据至块设备的速率(kb/s)

                system

                    in:interrupts,中断速率;

                    cs:context switch, 上下文 切换的速率;

                cpu

                    us: user space

                    sy:system

                    id:idle

                    wa:wait

                    st: stolen

        

            选项:

                -s:显示内存统计数据;

                

        pmap命令:

            - report memory map of a process

            

            pmap [options] pid [...]

                -x:显示详细格式的信息;

                

            另一种查看方式:cat  /proc/PID/maps

            

        glances命令:

            - A cross-platform curses-based monitoring tool

            

            内建命令:

                

            常用选项:

                -b:以Byte为单位显示网上数据速率;

                -d:关闭磁盘I/O模块;

                -m:关闭mount模块;

                -n:关闭network模块;

                -t #:刷新时间间隔;

                -1:每个cpu的相关数据单独显示;

                -o {HTML|CSV}:输出格式;

                -f  /PATH/TO/SOMEDIR:设定输出文件的位置;

            

            C/S模式下运行glances命令:

                服务模式:

                    glances  -s  -B  IPADDR

                    

                    IPADDR:本机的某地址,用于监听;

                    

                客户端模式:

                    glances  -c  IPADDR

                    

                    IPADDR:是远程服务器的地址;

                    

        dstat命令:

            - versatile tool for generating system resource statistics

            

            dstat [-afv] [options..] [delay [count]]

            

            常用选项:

                -c, --cpu:显示cpu相关信息;

                    -C #,#,...,total

                -d, --disk:显示磁盘的相关信息

                    -D sda,sdb,...,tobal

                -g:显示page相关的速率数据;

                -m:Memory的相关统计数据

                -n:Interface的相关统计数据;

                -p:显示process的相关统计数据;

                -r:显示io请求的相关的统计数据;

                -s:显示swapped的相关统计数据;

                

                --tcp

                --udp

                --raw

                --socket

                

                --ipc

                

                --top-cpu:显示最占用CPU的进程;

                --top-io:最占用io的进程;

                --top-mem:最占用内存的进程;

                --top-lantency:延迟最大的进程;

                

        kill命令:

            

            - terminate a process

            

            用于向进程发送信号,以实现对进程的管理;

            

            显示当前系统可用信号:

                kill -l [signal]

                

                每个信号的标识方法有三种:

                    1) 信号的数字标识;

                    2) 信号的完整名称;

                    3) 信号的简写名称;

                    

            向进程发信号:

                kill  [-s signal|-SIGNAL]  pid...

                

                常用信号:

                    1) SIGHUP:无须关闭进程而让其重读配置文件;

                    2)SIGINT:终止正在运行的进程,相当于Ctrl+c

                    9)SIGKILL:杀死运行中的进程;

                    15)SIGTERM:终止运行中的进程;

                    18)SIGCONT:

                    19)SIGSTOP:

                    

        killall命令:

            

            - kill processes by name

            

            killall  [-SIGNAL]  program

            

    Linux系统作业控制:

        

        job:

            前台作业(foregroud):通过终端启动,且启动后会一直占据终端;

            后台作业(backgroud):可以通过终端启动,但启动后即转入后台运行(释放终端);

            

        如何让作业运行于后台?

            (1) 运行中的作业

                Ctrl+z

                注意:送往后台后,作业会转为停止态;

            (2) 尚未启动的作业

                # COMMAND &

                

                注意:此类作业虽然被送往后台,但其依然与终端相关;如果希望把送往后台的作业剥离与终端的关系:

                    # nohup  COMMAND  &

                    

        查看所有的作业:

            # jobs

            

        可实现作业控制的常用命令:

            # fg  [[%]JOB_NUM]:把指定的作业调回前台;

            # bg  [[%]JOB_NUM]:让送往后台的作业在后台继续运行;

            # kill  %JOB_NUM:终止指定的作业;

            

    调整进程优先级:

        

        可通过nice值调整的优先级范围:100-139

            分别对应于:-20, 19

            

        进程启动时,其nice值默认为0,其优先级是120;

        

        nice命令:

            以指定的nice值启动并运行命令

                # nice  [OPTION]  [COMMAND [ARGU]...]

                    选项:

                        -n NICE

                        

                注意:仅管理员可调低nice值;

                

        renice命令:

            # renice  [-n]  NICE  PID...

            

        查看Nice值和优先级:

            ps  axo  pid, ni, priority, comm  

            

    未涉及到的命令:sar,  tsar,  iostat,  iftop,  nethog,  ...

    

    博客作业: htop/dstat/top/ps命令的使用;

    

网络客户端工具:

    

    ping/lftp/ftp/lftpget/wget等;

    

    ping命令:    

        send ICMP ECHO_REQUEST to network hosts

        ICMP:Internet Control Message Protocol        

        

        ping  [OPTION]  destination

            -c #:发送的ping包个数;

            -w #:ping命令超时时长;

            -W #:一次ping操作中,等待对方响应的超时时长;

            -s #:指明ping包报文大小;

        

    hping命令: (package: hping3)

        send (almost) arbitrary TCP/IP packets to network hosts

        

            --fast

            --faster

            --flood

            -i uX

        

    traceroute命令:

        - print the route packets trace to network host

        

        跟踪从源主机到目标主机之间经过的网关;

        

    ftp命令:

        ftp: File Transfer Protocol

            

            ftp服务命令行客户端工具;

            

    lftp命令:

        lftp  [-p port]  [-u user[,pass]] [site]

        

        get, mget

        put, mput

        rm, mrm

        

    lftpget命令:

        lftpget [-c] [-d] [-v] URL [URL...]

            -c:继续此前的下载;

            

    wget命令:

        The non-interactive network downloader.

        

        wget [option]... [URL]...

            -b:在后台执行下载操作;

            -q:静默模式,不显示下载进度;

            -O file:下载的文件的保存位置;

            -c:续传;

            --limit-rate=amount:以指定的速率传输文件;

            

bash脚本编程


    顺序执行

    选择执行: if, case

    循环执行:for, while, until

    

    for循环格式:

        for  VARAIBLE  in  LIST; do

            循环体

        done

        

    while循环:

        while  CONDITION; do

            循环体

            循环控制变量修正表达式

        done

        

        进入条件:CONDITION测试为”真“

        退出条件:CONDITION测试为”假“

        

    until循环:

        until  CONDITION; do

            循环体

            循环控制变量修正表达式

        done

        

        进入条件:CONDITION测试为”假“

        退出条件:CONDITION测试为”真“        

        

        示例:求100以内所有正整数之和;

            

            #!/bin/bash

            #

            declare -i sum=0

            declare -i i=1


            until [ $i -gt 100 ]; do

                let sum+=$i

                let i++

            done


            echo $sum            


            

            #!/bin/bash

            #

            declare -i sum=0

            declare -i i=1


            while [ $i -le 100 ]; do

                let sum+=$i

                let i++

            done


            echo $sum            


    练习:分别使用for, while, until实现

        1、分别求100以内所有偶数之和,100以内所奇数之和;

        2、创建10个用户,user101-user110;密码同用户名;

        3、打印九九乘法表;

        4、打印逆序的九九乘法表;

        

        1X1=1

        1X2=2  2X2=4

        1X3=3  2X3=6  3X3=9

        

        外循环控制乘数,内循环控制被乘数;

            #!/bin/bash

            #

            for j in {1..9}; do

                for i in $(seq 1 $j); do

                    echo -n -e "${i}X${j}=$[${i}*${j}]\t"

                done

                echo

            done    

            

CentOS系统启动流程


    Linux系统的组成部分:内核+根文件系统

        内核:进程管理、内存管理、网络协议栈、文件系统、驱动程序、安全功能

            IPC:Inter Process Communication

                消息队列、semerphor、shm

                socket

                

    运行中的系统环境可分为两层:内核空间、用户空间

        用户空间:应用程序(进程或线程)

        内核空间:内核代码(系统调用)

        

    内核设计流派:

        单内核设计:把所有功能集成于同一个程序;

            Linux

        微内核设计:每种功能使用一个单独的子系统实现;

            Windows, Solaris

            

        

        Linux内核特点:

            支持模块化:  .ko (kernel object)

            支持模块运行时动态装载或卸载;

            

            组成部分:

                核心文件:/boot/vmlinuz-VERSION-release

                ramdisk:

                    CentOS 5:/boot/initrd-VERSION-release.img

                    CentOS 6,7:/boot/initramfs-VERSION-release.img

                模块文件:/lib/modules/VERSION-release

                

    CentOS 系统的启动流程:

        

        POST:加电自检;

            ROM:CMOS

                BIOS:Basic Input and Output System

                

            ROM+RAM

            

        Boot Sequence:

            按次序查找各引导设备,第一个有引导程序的设备即为本次启动要用到的设备;

            

            bootloader:引导加载器,程序;

                    Windows:ntloader

                    Linux:

                        LILO:LIinux  LOader

                        GRUB:Grand Uniform Bootloader

                            GRUB 0.X:Grub Legacy

                            GRUB 1.X:Grub2

                            

                    功能:提供一个菜单,允许用户选择要启动的系统或不同的内核版本; 把用户选定的内核装载到RAM中的特定空间中,解压、展开,而后把系统控制权移交给内核;

                    

                MBR:Master Boot Record

                    512bytes:

                        446bytes:bootloader

                        64bytes:fat

                        2bytes:55AA

                        

                GRUB:

                    bootloader:1st stage

                    Partition:filesystem driver, 1.5 stage

                    Partition:/boot/grub, 2nd stage

                        

                注意:UEFI,GPT

            

            Kernel:

                自身初始化:

                    探测可识别到的所有硬件设备;

                    加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)

                    以只读方式挂载根文件系统;

                    运行用户空间的第一个应用程序:/sbin/init

                    

                init程序的类型:

                    CentOS 5-:SysV init

                        配置文件:/etc/inittab

                        

                    CentOS 6:Upstart

                        配置文件:/etc/inittab

                            /etc/init/*.conf

                            

                    CentOS 7:Systemd

                        配置文件:/usr/lib/systemd/system/, /etc/systemd/system/

                        

                ramdisk:

                    

                    Linux内核的特性之一:使用缓冲和缓存来加速对磁盘上的文件访问;

                    

                        ramdisk --> ramfs

                        

                        CentOS 5: initrd

                            工具程序:mkinitrd

                        CentOS 6,7: initramfs

                            工具程序:dracut, mkinitrd

                            

            系统初始化流程(内核级别): POST --> BootSequence(BIOS) --> BootLoader(MBR)--> Kernel(ramdisk)--> rootfs(readonly)--> /sbin/init ()

            

        /sbin/init:

            

            CentOS 5: SysV init

                

                运行级别:为了系统的运行或维护等目的而设定的机制;

                    0-6:7个级别;

                        0:关机, shutdown

                        1:单用户模式(single user),root用户,无须认证;维护模式;

                        2、多用户模式(multi user),会启动网络功能,但不会启动NFS;维护模式;

                        3、多用户模式(mutli user),完全功能模式;文本界面;

                        4、预留级别:目前无特别使用目的,但习惯以同3级别功能使用;

                        5、多用户模式(multi user), 完全功能模式,图形界面;

                        6、重启,reboot

                        

                    默认级别:3, 5

                    

                    级别切换:init #

                    

                    级别查看:

                        who -r

                        runlevel

                        

                配置文件:/etc/inittab

                    

                    每行定义一种action以及与之对应的process

                        id:runlevels:action:process

                            id:一个任务的标识符;

                            runlevels:在哪些级别启动此任务;#,###,也可以为空,表示所有级别;

                            action:在什么条件下启动此任务;

                            process:任务;

                            

                        action:

                            wait:等待切换至此任务所在的级别时执行一次;

                            respawn:一旦此任务终止,就自动重新启动之;

                            initdefault:设定默认运行级别;此时,process省略;

                            sysinit:设定系统初始化方式,此处一般为指定/etc/rc.d/rc.sysinit脚本;

                            

                        例如:

                            id:3:initdefault:

                            si::sysinit:/etc/rc.d/rc.sysinit

                            

                            l0:0:wait:/etc/rc.d/rc  0

                            l1:1:wait:/etc/rc.d/rc  1

                            …………

                            l6:6:wait:/etc/rc.d/rc  6

                                意味着去启动或关闭/etc/rc.d/rc3.d/目录下的服务脚本所控制服务;

                                    K*:要停止的服务;K##*,优先级,数字越小,越是优先关闭;依赖的服务先关闭,而后关闭被依赖的;

                                    S*:要启动的服务;S##*,优先级,数字越小,越是优先启动;被依赖的服务先启动,而依赖的服务后启动;

                                    

                                rc脚本:接受一个运行级别数字为参数;

                                    

                                    脚本框架:

                                        for  srv  in  /etc/rc.d/rc#.d/K*; do

                                            $srv  stop

                                        done

                                        

                                        for  srv  in  /etc/rc.d/rc#.d/S*; do

                                            $srv  start

                                        done

                                        

                                    /etc/init.d/* (/etc/rc.d/init.d/*)脚本执行方式:

                                        # /etc/init.d/SRV_SCRIPT  {start|stop|restart|status}

                                        # service  SRV_SCRIPT   {start|stop|restart|status}

                                        

                                    chkconfig命令:管控/etc/init.d/每个服务脚本在各级别下的启动或关闭状态;

                                        

                                        查看:chkconfig  --list   [name]

                                        

                                        添加:chkconfig  --add  name

                                        

                                            能被添加的服务的脚本定义格式之一:

                                                #!/bin/bash

                                                #

                                                # chkconfig: LLL  NN NN

                                                # description:  

                                                

                                        删除:chkconfig  --del  name

                                        修改指定的链接类型:

                                            chkconfig  [--level  LEVELS]  name  <on|off|reset>

                                                --level LEVELS:指定要控制的级别;默认为2345;

                                

                                注意:正常级别下,最后启动的一个服务S99local没有链接至/etc/init.d下的某脚本,而是链接至了/etc/rc.d/rc.local (/etc/rc.local)脚本;因此,不便或不需写为服务脚本的程序期望能开机自动运行时,直接放置于此脚本文件中即可。

                                

                            tty1:2345:respawn:/usr/sbin/mingetty tty1

                            ... ...

                            tty6:2345:respawn:/usr/sbin/mingetty tty6    

                            

                                (1)mingetty会调用login程序;

                                (2)打开虚拟终端的程序除了mingetty之外,还有诸如getty等;

                                

                    

                        系统初始化脚本:/etc/rc.d/rc.sysinit

                            (1) 设置主机名;

                            (2) 设置欢迎信息;

                            (3) 激活udev和selinux;

                            (4) 挂载/etc/fstab文件中定义的所有文件系统;

                            (5) 检测根文件系统,并以读写方式重新挂载根文件系统;

                            (6) 设置系统时钟;

                            (7) 根据/etc/sysctl.conf文件来设置内核参数;

                            (8) 激活lvm及软raid设备;

                            (9) 激活swap设备;

                            (10) 加载额外设备的驱动程序;

                            (11) 清理操作;

                                

                总结(用户空间的启动流程): /sbin/init (/etc/inittab)

                    设置默认运行级别 --> 运行系统初始化脚本,完成系统初始化 --> 关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务--> 设置登录终端 [--> 启动图形终端]

                    

            CentOS 6:

                

                init程序:upstart,但依然为/sbin/init,其配置文件:

                    /etc/init/*.conf, /etc/inittab(仅用于定义默认运行级别)

                    

                        注意:*.conf为upstart风格的配置文件;

                            

                        rcS.conf

                        rc.conf

                        start-ttys.conf

                        

            CentOS 7:

                

                init程序:systemd,配置文件:/usr/lib/systemd/system/*,  /etc/systemd/system/*

                

                完全兼容SysV脚本机制;因此,service命令依然可用;不过,建议使用systemctl命令来控制服务;

                

                    # systemctl  {start|stop|restart|status}  name[.service]

                    

        博客作业:CentOS系统启动流程;

        

回顾:

    

    CentOS 6启动流程:

        POST --> Boot Sequence(BIOS) --> Boot Loader (MBR) --> Kernel(ramdisk) --> rootfs --> switchroot --> /sbin/init -->(/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别 --> 系统初始化脚本 --> 关闭或启动对应级别下的服务 --> 启动终端


GRUB(Boot Loader):


    grub: GRand Unified Bootloader

        grub 0.x: grub legacy

        grub 1.x: grub2


    grub legacy:

        stage1: mbr

        stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统;

        stage2:磁盘分区(/boot/grub/)


        配置文件:/boot/grub/grub.conf <-- /etc/grub.conf


        stage2及内核等通常放置于一个基本磁盘分区;

            功用:

                (1) 提供菜单、并提供交互式接口

                    e: 编辑模式,用于编辑菜单;

                    c: 命令模式,交互式接口;

                (2) 加载用户选择的内核或操作系统

                    允许传递参数给内核

                    可隐藏此菜单

                (3) 为菜单提供了保护机制

                    为编辑菜单进行认证

                    为启用内核或操作系统进行认证


        如何识别设备:

            (hd#,#)

                hd#: 磁盘编号,用数字表示;从0开始编号

                #: 分区编号,用数字表示; 从0开始编号


                (hd0,0)


        grub的命令行接口

            help: 获取帮助列表

            help KEYWORD: 详细帮助信息

            find (hd#,#)/PATH/TO/SOMEFILE:

            root (hd#,#)

            kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;额外还可以添加许多内核支持使用的cmdline参数;

                例如:init=/path/to/init, selinux=0

            initrd /PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk;

            boot: 引导启动选定的内核;


            手动在grub命令行接口启动系统:

                grub> root (hd#,#)

                grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE

                grub> initrd /initramfs-VERSION-RELEASE.img

                grub> boot


        配置文件:/boot/grub/grub.conf

            配置项:

                default=#: 设定默认启动的菜单项;落单项(title)编号从0开始;

                timeout=#:指定菜单项等待选项选择的时长;

                splashimage=(hd#,#)/PATH/TO/XPM_PIC_FILE:指明菜单背景图片文件路径;

                hiddenmenu:隐藏菜单;

                password [--md5] STRING: 菜单编辑认证;

                title TITLE:定义菜单项“标题”, 可出现多次;

                    root (hd#,#):grub查找stage2及kernel文件所在设备分区;为grub的“根”;

                    kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核

                    initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件;

                    password [--md5] STRING: 启动选定的内核或操作系统时进行认证;



            grub-md5-crypt命令


        进入单用户模式:

            (1) 编辑grub菜单(选定要编辑的title,而后使用e命令);

            (2) 在选定的kernel后附加

                1, s, S或single都可以;

            (3) 在kernel所在行,键入“b”命令;


        安装grub:

            (1) grub-install

                grub-install --root-directory=ROOT /dev/DISK

            

            (2) grub

                grub> root (hd#,#)

                grub> setup (hd#)


        练习:

            1、新加硬盘,提供直接单独运行bash系统;

            2、破坏本机grub stage1,而后在救援模式下修复之;

            3、为grub设置保护功能;


    博客作业:grub应用;

    

Linux Kernel:

    

        CentOS启动流程:POST --> Bootloader(BIOS, MBR) --> Kernel(initrd) --> rootfs --> switch_root --> /sbin/init

            root    (hd0,0)

            kernel

            initrd

            

        ldd命令:

                - print shared library dependencies

                ldd [OPTION]... FILE...

                

    内核设计体系:单内核、微内核

        Linux:单内核设计,但充分借鉴了微内核体系的设计的优点;为内核引入了模块化机制;

            内核的组成部分:

                kernel:内核核心,一般为bzImage,通常位于/boot目录,名称为vmlinuz-VERSION-release;

                kernel object:内核对象,即内核模块,一般放置于/lib/modules/VERSION-release/

                    内核模块与内核核心版本一定要严格匹配;

                    

                    [   ]:N

                    [M]:Module

                    [*]:Y,编译进内核核心

                    

                    内核:动态装载和卸载;

                    

                ramdisk:辅助性文件,并非必须,这取决于内核是否能直接驱动rootfs所在的设备;

                    目标设备驱动,例如SCSI设备的驱动;

                    逻辑设备驱动,例如LVM设备的驱动;

                    文件系统,例如xfs文件系统;

                    

                    ramdisk:是一个简装版的根文件系统;

                    

        内核信息获取:

            uname命令:

                - print system information

                

                格式:uname [OPTION]...

                    -r:内核的release号

                    -n:主机名

                    

                文件:/boot/vmlinuz-VERSION-release

                    

        模块信息获取和管理:

            

            lsmod命令:

                - Show the status of modules in the Linux Kernel

                

                显示的内核来自于/proc/modules

                

            modinfo命令:

                - Show information about a Linux Kernel module

                

                modinfo [-F field] [-k kernel] [modulename|filename...]

                    -F field: 仅显示指定字段的信息;

                    -n:显示文件路径;

                    

            modprobe命令:

                - Add and remove modules from the Linux Kernel

                

                格式:modprobe  [-r]  module_name

                    模块的动态装载:modprobe  module_name

                    动态卸载:modprobe  -r  module_name

                    

            depmod命令:

                - Generate modules.dep and map files.

                

                内核模块依赖关系文件的生成工具;

                

            模块的装载和卸载的另一组命令:

                insmod命令:

                    insmod  [filename]  [module options...]

                        filename:模块文件的文件路径;

                    

                rmmod命令:

                    rmmod  [module_name]

                    

        ramdisk文件的管理:

            (1) mkinitrd命令

                为当前使用中的内核重新制作ramdisk文件:

                    # mkinitrd [OPTION...] [<initrd-image>] <kernel-version>

                        --with=<module>:除了默认的模块之外需要装载至initramfs中的模块;

                        --preload=<module>:initramfs所提供的模块需要预先装载的模块;

                    

                    示例: ~]# mkinitrd  /boot/initramfs-$(uname -r).img   $(uname -r)

            

            (2) dracut命令

                 - low-level tool for generating an initramfs image

                    # dracut [OPTION...] [<image> [<kernel version>]]

                    

                    示例: ~]# dracut /boot/initramfs-$(uname -r).img  $(uname -r)

                    

        内核信息输出的伪文件系统:

            /proc:内核状态和统计信息的输出接口;同时,还提供一个配置接口,/proc/sys;

                参数:

                    只读:信息输出;例如/proc/#/*

                    可写:可接受用户指定一个“新值”来实现对内核某功能或特性的配置;/proc/sys/

                    

                        /proc/sys:

                            net/ipv4/ip_forward  相当于  net.ipv4.ip_forward

                        

                        (1) sysctl命令

                            专用于查看或设定/proc/sys目录下参数的值;

                                sysctl [options]  [variable[=value]]

                                    查看:

                                        # sysctl  -a

                                        # sysctl  variable        

                                    修改其值:

                                        # sysctl  -w  variable=value

                        (2) 文件系统命令(cat, echo)

                            查看:

                                # cat  /proc/sys/PATH/TO/SOME_KERNEL_FILE

                            设定:

                                # echo  "VALUE"  > /proc/sys/PATH/TO/SOME_KERNEL_FILE

                            

                        注意:上述两种方式的设定仅当前运行内核有效;

                        

                        (3) 配置文件:/etc/sysctl.conf,  /etc/sysctl.d/*.conf

                            立即生效的方式:sysctl  -p  [/PATH/TO/CONFIG_FILE]

                            

                    内核参数:

                        net.ipv4.ip_forward:核心转发;

                        vm.drop_caches:

                        kernel.hostname:主机名;

                        net.ipv4.icmp_echo_ignore_all:忽略所有ping操作;

                        

            /sys目录:

                

                sysfs:输出内核识别出的各硬件设备的相关属性信息,也有内核对硬件特性的可设置参数;对此些参数的修改,即可定制硬件设备工作特性;

                

                udev:通过读取/sys目录下的硬件设备信息按需为各硬件设备创建设备文件;udev是用户空间程序;专用工具:devadmin, hotplug;

                

                udev为设备创建设备文件时,会读取其事先定义好的规则文件,一般在/etc/udev/rules.d/目录下,以及/usr/lib/udev/rules.d/目录下;

                

        

回顾:内核

    

    内核的组成部分:kernel, kernel object, ramdisk

        kernel: uname

        kernel object: lsmod, modinfo, modprobe, insmod, rmmod, depmod

        ramdisk:mkinitrd, dracut

        

    启动流程: POST --> BootSequence(BIOS) --> Bootloader (MBR) --> kernel (ramdisk) --> rootfs (switch_root) --> /sbin/init (/etc/inittab, /etc/init/*.conf, /usr/lib/systemd/system/)--> 默认运行级别、系统初始化、关闭及启动服务、启动终端(图形终端)

    

    grub:

        1st stage:mbr

        1_5 stage: mbr之后的扇区

        2nd stage:/boot/grub/

            

        加密:编辑、内核

    

编译内核:

    

    程序包的编译安装:

        ./configure, make, make install

        

    前提:开发环境(开发工具,开发库),头文件:/usr/include

    

    开源:源代码 --> 可执行格式

        发行版:以“通用”的目标;

        

    前提:

        (1) 准备好开发环境;

        (2) 获取目标主机上硬件设备的相关信息;

        (3) 获取到目标主机系统功能的相关信息,例如要启用的文件系统;

        (4) 获取内核源代码包:www.kernel.org

        

        准备开发环境:

            CentOS 6.7:

                包组:

                    Development Tools

                    Server Platform Development

                    

            CentOS 7:

                包组:

                    Development Tools

                    Server Platform Development

                    

                包:

                    ncurses-devel

                    

        获取目标主机上硬件设备的相关信息:

            CPU:

                ~]# cat  /proc/info

                ~]# lscpu

                ~]# x86info -a

                

            PCI设备:

                ~]# lspci

                    -v

                    -vv

                    

                ~]# lsusb

                    -v

                    -vv

                    

                ~]# lsblk

                

            了解全部硬件设备信息:

                ~]# hal-device

                

        内核编译过程:

            步骤:

                ~]# tar  xf  linux-3.10.67.tar.xz  -C  /usr/src

                ~]# cd  /usr/src

                ~]# ln  -s  linux-3.10.67  linux

                ~]# cd  linux

                

                ~]# make menuconfig           配置内核选项

                ~]# make  [-j #]            编译内核,可使用-j指定编译线程数量

                ~]# make modules_install    安装内核模块

                ~]# make install            安装内核

                

                重启系统,选择使用新内核;

                

            screen命令:

                打开screen: ~]# screen

                拆除screen: Ctrl+a, d

                列出screen: ~]# screen  -ls

                连接至screen: ~]# screen  -r   SCREEN_ID

                关闭screen:  ~]# exit

        

        过程的详细说明:

            (1)  配置内核选项

                支持“更新”模式进行配置:在已有的.config文件的基础之上进行“修改”配置;

                    (a) make config:基于命令行以遍历的方式去配置内核中可配置的每个选项;

                    (b) make  menuconfig:基于cureses的文本配置窗口;

                    (c) make  gconfig:基于GTK开发环境的窗口界面;  包组“桌面平台开发”

                    (d) make  xonfig:基于QT开发环境的窗口界面;

                支持“全新配置”模式进行配置:

                    (a) make  defconfig:基于内核为目标平台提供的“默认”配置为模板进行配置;

                    (b) make   allnoconfig:所有选项均为“no”;

                    

            (2) 编译

                

                 (a) 多线程编译:make  [-j #]

                 (b) 编译内核中的一部分代码:

                    (i) 只编译某子目录中的相关代码:

                        # cd  /usr/src/linux

                        # make  path/to/dir/

                        

                    (ii)只编译一个特定的模块

                        # cd  /usr/src/linux

                        # make  path/to/dir/file.ko

                (c) 如何交叉编译:

                    目标平台与当前编译操作所在的平台不同;

                    

                    # make  ARCH=arch_name

                    

                    要获取特定目标平台的使用帮助:                    

                        # make  ARCH=arch_name help

                        

            (3) 如何在执行过编译操作的内核源码树上做重新编译:

                事先清理操作:

                    # make clean:清理编译生成的绝大多数文件,但会保留config,及编译外部模块所需要的文件;

                    # make mrproper:清理编译生成的所有文件,包括配置生成的config文件及某些备份文件;

                    # make distclean:相当于mrproper,额外清理各种patches以及编辑器备份文件;

                    

CentOS 系统安装:

    

    安装程序:anaconda

    

        bootloader --> kernel(initrd(rootfs)) --> anaconda

        

        anaconda:

            tui:基于cureses的文本配置窗口

            gui:图形界面

            

        CentOS的安装过程启动流程:

            MBR:boot.cat

            Stage2:isolinux/isolinux.bin

                配置文件:isolinux/isolinux.cfg

                

                每个对应的菜单选项:

                    加载内核:isolinux/vmlinuz

                    向内核传递参数:append  initrd=initrd.img

                    

                装载根文件系统,并启动anaconda

                

                    默认界面是图形界面:512MB+内存空间;

                    若需要显式指定启动TUI接口: 向启动内核传递一个参数"text"即可;

                    

                        ESC,

                            boot: linux  text

        

                

                 注意:上述内容一般位于引导设备,例如可通过光盘、U盘或网络等;后续的anacona及其安装用到的程序包等可以来自于程序包仓库,此仓库的位置可以为:

                    本地光盘

                    本地硬盘

                    ftp server

                    http server

                    nfs server

                    

                    如果想手动指定安装仓库:

                        ESC

                            boot: linux method

                            

        anaconda的工作过程:

            安装前配置阶段

                安装过程使用的语言;

                键盘类型

                安装目标存储设备

                    Basic Storage:本地磁盘

                    Special Storage: iSCSI

                设定主机名

                配置网络接口

                时区

                管理员密码

                设定分区方式及MBR的安装位置;

                创建一个普通用户;

                选定要安装的程序包;

            安装阶段

                在目标磁盘创建分区并执行格式化;

                将选定的程序包安装至目标位置;

                安装bootloader;

            首次启动

                iptables

                selinux

                core dump

                

        anaconda的配置方式:

            (1) 交互式配置方式;

            (2) 支持通过读取配置文件中事先定义好的配置项自动完成配置;遵循特定的语法格式,此文件即为kickstart文件;

            

        安装引导选项:

            boot:

                text:文本安装方式

                method:手动指定使用的安装方法

                与网络相关的引导选项:

                    ip=IPADDR

                    netmask=MASK

                    gateway=GW

                    dns=DNS_SERVER_IP

                远程访问功能相关的引导选项:

                    vnc

                    vncpassword='PASSWORD'

                启动紧急救援模式:

                    rescue

                装载额外驱动:

                    dd

                    

                www.redhat.com/docs , 《installation guide》

                

回顾:

    内核编译、CentOS系统安装

        内核编译:

            make menuconfig

            make  [-j  #]

            make  modules_install

            make  install

            

        CentOS系统安装:

            bootloader --> isolinux/vmlinuz (isolinux/initrd) --> anaconda

                

                anaconda

                    安装前配置阶段

                        交互式配置

                        配置文件(自动配置)

                    安装阶段

                    首次启动

                    

CentOS系统安装:

    

    CentOS 6.7 x86_64:

        minimal install

        

    安装引导选项:

        ks:指明kickstart文件的位置;

            ks=

                DVD drive: ks=cdrom:/PATH/TO/KICKSTART_FILE

                Hard Drive: ks=hd:/DEVICE/PATH/TO/KICKSTART_FILE

                HTTP Server: ks=http://HOST[:PORT]/PATH/TO/KICKSTART_FILE

                FTP Server:  ks=ftp://HOST[:PORT]/PATH/TO/KICKSTART_FILE

                HTTPS Server:   ks=https://HOST[:PORT]/PATH/TO/KICKSTART_FILE

        

    kickstart文件的格式

        命令段:

            指定各种安装前配置选项,如键盘类型等;

                必备命令

                可选命令

        程序包段:

            指明要安装程序包,以及包组,也包括不安装的程序包;

                %packages

                @group_name

                package

                -package

                %end

        脚本段:

            %pre:安装前脚本

                运行环境:运行安装介质上的微型Linux系统环境;

            

            %post:安装后脚本

                运行环境:安装完成的系统;

                

                

        命令段中的必备命令:

            authconfig:认证方式配置

                authconfig  --enableshadow  --passalgo=sha512

            bootloader:定义bootloader的安装位置及相关配置

                bootloader  --location=mbr  --driveorder=sda  --append="crashkernel=auto rhgb quiet"

            keyboard:设置键盘类型

                keyboard us

            lang:语言类型

                lang  zh_CN.UTF-8

            part:分区布局;

                part  /boot  --fstype=ext4  --size=500

                part  pv.008002  --size=51200

            rootpw:管理员密码

                rootpw   --iscrypted  $6$4Yh15kMGDWOPtbbW$SGax4DsZwDAz4201.O97WvaqVJfHcISsSQEokZH054juNnoBmO/rmmA7H8ZsD08.fM.Z3Br/67Uffod1ZbE0s.

            timezone:时区

                timezone  Asia/Shanghai

                

            补充:分区相关的其它指令

                clearpart:清除分区

                    clearpart  --none  --drives=sda:清空磁盘分区;

                volgroup:创建卷组

                    volgroup  myvg  --pesize=4096  pv.008002

                logvol:创建逻辑卷

                    logvol  /home  --fstype=ext4  --name=lv_home  --vgname=myvg  --size=5120

                    

                生成加密密码的方式:

                    ~]# openssl  passwd  -1  -salt `openssl rand -hex 4`

        

        可选命令:

            install  OR  upgrade:安装或升级;

            text:安装界面类型,text为tui,默认为GUI

            network:配置网络接口

                network  --onboot yes  --device eth0  --bootproto dhcp  --noipv6

            firewall:防火墙

                firewall  --disabled

            selinux:SELinux

                selinux --disabled

            halt、poweroff或reboot:安装完成之后的行为;

            repo:指明安装时使用的repository;

                repo  --name="CentOS"   --baseurl=cdrom:sr0  --cost=100

            url: 指明安装时使用的repository,但为url格式;

                url --url=http://172.16.0.1/cobbler/ks_mirror/CentOS-6.7-x86_64/    

                

        参考官方文档:《Installation Guide》

                    

            系统安装完成之后禁用防火墙:

                CentOS 6:

                    # service iptables  stop

                    # chkconfig  iptables  off

                CentOS 7:

                    # systemctl  stop  firewalld.service

                    # systemctl  disable  firewalld.service

                    

            系统安装完成后禁用SELinux:

                编辑/etc/sysconfig/selinux或/etc/selinux/config文件,修改SELINUX参数的值为下面其中之一:

                    permissive

                    disabled

                    

                立即生效:

                    # getenforce

                    # setenforce  0

            

        定制kickstart文件:

            # yum install  system-config-kickstart

            # system-config-kickstart

            

            检查语法错误:

            # ksvalidator

    

    创建光盘镜像:

        ~]# mkisofs -R -J -T -v --no-emul-boot --boot-load-size 4 --boot-info-table -V "CentOS 6 x86_64 boot" -c isolinux/boot.cat -b isolinux/isolinux.bin -o  /root/boot.iso   myboot/

        

mkisofs -R -J -T -v --no-emul-boot --boot-load-size 4 --boot-info-table -V "CentOS 7 boot" -c isolinux/boot.cat -b isolinux/isolinux.bin -o /root/boot.iso myboot/


bash脚本编程:

    顺序执行

    选择分支

    循环执行

        for, while, until

        

        进入条件:

            for:列表元素非空;

            while:条件测试结果为“真”

            unitl:条件测试结果为“假”

        退出条件:

            for:列表元素遍历完成;

            while:条件测试结果为“假”

            until:条件测试结果为“真”

            

        循环控制语句:

            continue:提前结束本轮循环,而直接进入下一轮循环判断;

                while  CONDITION1; do

                    CMD1

                    ...

                    if  CONDITION2; then

                        continue

                    fi

                    CMDn

                    ...

                done

                

                示例:求100以内所有偶数之和;                                        

                    #!/bin/bash

                    #

                    declare -i evensum=0

                    declare -i i=0


                    while [ $i -le 100 ]; do

                        let i++

                        if [ $[$i%2] -eq 1 ]; then

                            continue

                        fi

                        let evensum+=$i

                    done


                    echo "Even sum: $evensum"                

            

            break:提前跳出循环

                while  CONDITION1; do

                    CMD1

                    ...

                    if  CONDITION2; then

                        break

                    fi

                done

                

        创建死循环:

            while true; do

                循环体

            done

            

            退出方式:

                某个测试条件满足时,让循环体执行break命令;

                

            示例:求100以内所奇数之和

                #!/bin/bash

                #

                declare -i oddsum=0

                declare -i i=1


                while true; do

                    let oddsum+=$i

                    let i+=2

                    if [ $i -gt 100 ]; then

                        break

                    fi

                done

                

            sleep命令:

                - delay for a specified amount of time

            

                sleep NUMBER

                

            练习:每隔3秒钟到系统上获取已经登录用户的用户的信息;其中,如果logstash用户登录了系统,则记录于日志中,并退出;

                #!/bin/bash

                #

                while true; do

                    if who | grep "^logstash\>" &> /dev/null; then

                        break

                    fi

                    sleep 3

                done


                echo "$(date +"%F %T") logstash logged on" >> /tmp/users.log    

                

                #!/bin/bash

                #

                until who | grep "^logstash\>" &> /dev/null; do

                    sleep 3

                done


                echo "$(date +"%F %T") logstash logged on" >> /tmp/users.log            

            

        while循环的特殊用法(遍历文件的行):

            

            while  read  VARIABLE; do

                循环体;

            done  <  /PATH/FROM/SOMEFILE

            

            依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将基赋值给VARIABLE变量;

            

            示例:找出ID号为偶数的用户,显示其用户名、ID及默认shell;

                #!/bin/bash

                #

                while read line; do

                    userid=$(echo $line | cut -d: -f3)

                    username=$(echo $line | cut -d: -f1)

                    usershell=$(echo $line | cut -d: -f7)


                    if [ $[$userid%2] -eq 0 ]; then

                        echo "$username, $userid, $usershell."

                    fi

                done < /etc/passwd                

                            

        for循环的特殊用法:

            for  ((控制变量初始化;条件判断表达式;控制变量的修正语句)); do

                循环体

            done

            

            控制变量初始化:仅在循环代码开始运行时执行一次;

            控制变量的修正语句:每轮循环结束会先进行控制变量修正运算,而后再做条件判断;

            

            示例:求100以内所有正整数之和

                #!/bin/bash

                #

                declare -i sum=0


                for ((i=1;i<=100;i++)); do

                    let sum+=$i

                done


                echo "Sum: $sum."

                

            示例:打印九九乘法表

                #!/bin/bash

                #

                for ((j=1;j<=9;j++)); do

                    for ((i=1;i<=j;i++)); do

                        echo -e -n "${i}X${j}=$[${i}*${j}]\t"

                    done

                    echo

                done                

                            

回顾:循环

    

    循环控制:break, continue

    while,for循环的特殊用法

    

    for (()); do

        循环体

    done

    

    while read VARAIBLE; do

        循环体

    done < /PATH/FROM/SOMEFILE

    

bash脚本编程:


    case语句:

        

        多分支if语句:

            if CONDITION1; then

                分支1

            elif  CONDITION2; then

                分支2

            ...

            else CONDITION; then

                分支n

            fi

            

        示例1:显示一个菜单给用户;

            cpu) display cpu information

            mem) display memory information

            disk) display disks information

            quit) quit

            

            要求:(1) 提示用户给出自己的选择;

                   (2) 正确的选择则给出相应的信息;否则,则提示重新选择正确的选项;

                   

                #!/bin/bash

                #

                cat << EOF

                cpu) display cpu information

                mem) display memory infomation

                disk) display disks information

                quit) quit

                ===============================

                EOF


                read -p "Enter your option: " option


                while [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]; do

                    echo "cpu, mem, disk, quit"

                    read -p "Enter your option again: " option

                done


                if [ "$option" == "cpu" ]; then

                    lscpu

                elif [ "$option" == "mem" ]; then

                    free -m

                elif [ "$option" == "disk" ]; then

                    fdisk -l /dev/[hs]d[a-z]

                else

                    echo "quit"

                    exit 0

                fi        

    

            case语句的语法格式:

                

                case  $VARAIBLE  in  

                PAT1)

                    分支1

                    ;;

                PAT2)

                    分支2

                    ;;

                ...

                *)

                    分支n

                    ;;

                esac

                

                case支持glob风格的通配符:

                    *:任意长度的任意字符;

                    ?:任意单个字符;

                    []:范围内任意单个字符;

                    a|b:a或b;

                

            示例:写一个服务框架脚本;

                $lockfile,  值/var/lock/subsys/SCRIPT_NAME

                

                (1) 此脚本可接受start, stop, restart, status四个参数之一;

                (2) 如果参数非此四者,则提示使用帮助后退出;

                (3) start,则创建lockfile,并显示启动;stop,则删除lockfile,并显示停止;restart,则先删除此文件再创建此文件,而后显示重启完成;status,如果lockfile存在,则显示running,否则,则显示为stopped.

                

                    #!/bin/bash

                    #

                    # chkconfig: - 50 50

                    # description: test service script

                    #

                    prog=$(basename $0)

                    lockfile=/var/lock/subsys/$prog


                    case $1  in

                    start)

                        if [ -f $lockfile ]; then

                            echo "$prog is running yet."

                        else

                            touch $lockfile

                            [ $? -eq 0 ] && echo "start $prog finshed."

                        fi

                        ;;

                    stop)

                        if [ -f $lockfile ]; then

                            rm -f $lockfile

                            [ $? -eq 0 ] && echo "stop $prog finished."

                        else

                            echo "$prog is not running."

                        fi

                        ;;

                    restart)

                        if [ -f $lockfile ]; then

                            rm -f $lockfile

                            touch $lockfile

                            echo "restart $prog finished."

                        else

                            touch -f $lockfile

                            echo "start $prog finished."

                        fi

                        ;;

                    status)

                        if [ -f $lockfile ]; then

                            echo "$prog is running"

                        else

                            echo "$prog is stopped."

                        fi

                        ;;

                    *)

                        echo "Usage: $prog {start|stop|restart|status}"

                        exit 1

                    esac

            

    函数:function

        过程式编程:代码重用

            模块化编程

            结构化编程

            

            把一段独立功能的代码当作一个整体,并为之一个名字;命名的代码段,此即为函数;

            

            注意:定义函数的代码段不会自动执行,在调用时执行;所谓调用函数,在代码中给定函数名即可;

                函数名出现的任何位置,在代码执行时,都会被自动替换为函数代码;

                

        语法一:

            function  f_name  {

                ...函数体...

            }

            

        语法二:

            f_name()  {

                ...函数体...

            }

            

        函数的生命周期:每次被调用时创建,返回时终止;

            其状态返回结果为函数体中运行的最后一条命令的状态结果;

            自定义状态返回值,需要使用:return

                return [0-255]

                    0: 成功

                    1-255: 失败

                

        示例:给定一个用户名,取得用户的id号和默认shell;

            #!/bin/bash

            #


            userinfo() {

                if id "$username" &> /dev/null; then

                    grep "^$username\>" /etc/passwd | cut -d: -f3,7

                else

                    echo "No such user."

                fi

            }


            username=$1

            userinfo


            username=$2

            userinfo            

            

        示例2:服务脚本框架

            #!/bin/bash

            #

            # chkconfig: - 50 50

            # description: test service script

            #

            prog=$(basename $0)

            lockfile=/var/lock/subsys/$prog


            start() {

                if [ -f $lockfile ]; then

                    echo "$prog is running yet."

                else

                    touch $lockfile

                    [ $? -eq 0 ] && echo "start $prog finshed."

                fi

            }


            stop() {

                if [ -f $lockfile ]; then

                    rm -f $lockfile

                    [ $? -eq 0 ] && echo "stop $prog finished."

                else

                    echo "$prog is not running."

                fi

            }

            status() {

                if [ -f $lockfile ]; then

                    echo "$prog is running"

                else

                    echo "$prog is stopped."

                fi

            }


            usage() {

                echo "Usage: $prog {start|stop|restart|status}"

            }


            case $1 in

            start)

                start ;;

            stop)

                stop ;;

            restart)

                stop

                start ;;

            status)

                status ;;

            *)

                usage

                exit 1 ;;

            esac

            

        函数返回值:

            函数的执行结果返回值:

                (1) 使用echo或printf命令进行输出;

                (2) 函数体中调用的命令的执行结果;

            函数的退出状态码:

                (1) 默认取决于函数体中执行的最后一条命令的退出状态码;

                (2) 自定义:return

                

        函数可以接受参数:

            传递参数给函数:

                在函数体中当中,可以使用$1,$2, ...引用传递给函数的参数;还可以函数中使用$*或$@引用所有参数,$#引用传递的参数的个数;

                在调用函数时,在函数名后面以空白符分隔给定参数列表即可,例如,testfunc  arg1 arg2 arg3 ...

                

            示例:添加10个用户,

                添加用户的功能使用函数实现,用户名做为参数传递给函数;

                

                    #!/bin/bash

                    #

                    # 5: user exists


                    addusers() {

                        if id $1 &> /dev/null; then

                            return 5

                        else

                            useradd $1

                            retval=$?

                            return $retval

                        fi

                    }


                    for i in {1..10}; do

                        addusers ${1}${i}

                        retval=$?

                        if [ $retval -eq 0 ]; then

                            echo "Add user ${1}${i} finished."

                        elif [ $retval -eq 5 ]; then

                            echo "user ${1}${i} exists."

                        else

                            echo "Unkown Error."

                        fi

                    done

            

        练习:写一个脚本;

            使用函数实现ping一个主机来测试主机的在线状态;主机地址通过参数传递给函数;

            主程序:测试172.16.1.1-172.16.67.1范围内各主机的在线状态;

            

        练习:写一个脚本;

            打印NN乘法表;

            

        变量作用域:

            局部变量:作用域是函数的生命周期;在函数结束时被自动销毁;

                定义局部变量的方法:local VARIABLE=VALUE

            本地变量:作用域是运行脚本的shell进程的生命周期;因此,其作用范围为当前shell脚本程序文件;

            

            示例程序:

                #!/bin/bash

                #

                name=tom


                setname() {

                    local name=jerry

                    echo "Function: $name"

                }


                setname

                echo "Shell: $name"

        

        函数递归:

            函数直接或间接调用自身;

                

            10!=10*9!=10*9*8!=10*9*8*7!=...

                n

                    n*(n-1)!=n*(n-1)*(n-2)!=


                #!/bin/bash

                #

                fact() {

                    if [ $1 -eq 0 -o $1 -eq 1 ]; then

                        echo 1

                    else

                        echo $[$1*$(fact $[$1-1])]

                    fi

                }


                fact $1                    

                    

                    

            1,1,2,3,5,8,13,21,...

                                    

                #!/bin/bash

                #

                fab() {

                    if [ $1 -eq 1 ]; then

                        echo -n "1 "

                    elif [ $1 -eq 2 ]; then

                        echo -n "1 "

                    else

                        echo -n "$[$(fab $[$1-1])+$(fab $[$1-2])] "

                    fi

                }


                for i in $(seq 1 $1); do

                    fab $i

                done

                echo                

                        

Sysmted:

    

    POST --> Boot Sequeue(BIOS) --> Bootloader(MBR) --> Kernel(ramdisk) --> rootfs --> /sbin/init

        init:

            CentOS 5: SysV init

            CentOS 6:Upstart

            CentOS 7:Systemd

            

        Systemd的新特性:

            系统引导时实现服务并行启动;

            按需激活进程;

            系统状态快照;

            基于依赖关系定义服务控制逻辑;

            

        核心概念:unit

            unit由其相关配置文件进行标识、识别和配置;文件中主要包含了系统服务、监听的socket、保存的快照以及其它与init相关的信息; 这些配置文件主要保存在:

                /usr/lib/systemd/system

                /run/systemd/system

                /etc/systemd/system

            

        unit的常见类型:

            Service unit:文件扩展名为.service,用于定义系统服务;

            Target unit:文件扩展为.target,用于模拟实现“运行级别”;

            Device unit: .device,用于定义内核识别的设备;

            Mount unit: .mount,定义文件系统挂载点;

            Socket unit: .socket,用于标识进程间通信用到的socket文件;

            Snapshot unit: .snapshot, 管理系统快照;

            Swap unit: .swap, 用于标识swap设备;

            Automount unit: .automount,文件系统自动点设备;

            Path unit: .path, 用于定义文件系统中的一文件或目录;

            

        关键特性:

            基于socket的激活机制:socket与程序分离;

            基于bus的激活机制;

            基于device的激活机制;

            基于Path的激活机制;

            系统快照:保存各unit的当前状态信息于持久存储设备中;

            向后兼容sysv init脚本;

                /etc/init.d/

                

        不兼容:

            systemctl的命令是固定不变的;

            非由systemd启动的服务,systemctl无法与之通信;

            

        管理系统服务:

            CentOS 7: service类型的unit文件;

            

                syscemctl命令:

                    - Control the systemd system and service manager

                    

                    systemctl  [OPTIONS...]  COMMAND  [NAME...]

                    

                        启动: service  NAME  start  ==>  systemctl  start  NAME.service

                        停止: service  NAME  stop  ==> systemctl  stop  NAME.service

                        重启: service  NAME  restart  ==>  systemctl  restart  NAME.service

                        状态: service  NAME  status  ==>  systemctl  status  NAME.service

                        条件式重启:service  NAME  condrestart  ==>  systemctl  try-restart  NAME.service

                        重载或重启服务: systemctl  reload-or-restart  NAME.servcie

                        重载或条件式重启服务:systemctl  reload-or-try-restart  NAME.service

                        

                        查看某服务当前激活与否的状态: systemctl  is-active  NAME.service

                        查看所有已激活的服务:systemctl  list-units  --type  service

                        查看所有服务(已激活及未激活): chkconfig --lsit  ==>  systemctl  list-units  -t  service  --all

                        

                        设置服务开机自启: chkconfig  NAME  on  ==>  systemctl  enable  NAME.service

                        禁止服务开机自启: chkconfig  NAME  off  ==>  systemctl  disable  NAME.service

                        查看某服务是否能开机自启: chkconfig  --list  NAME  ==>  systemctl  is-enabled  NAME.service

                        

                        禁止某服务设定为开机自启: systemctl  mask  NAME.service

                        取消此禁止: systemctl  unmask  NAME.servcie

                        

                        查看服务的依赖关系:systemctl  list-dependencies  NAME.service

                        

        管理target units:

            

            运行级别:

                0  ==>  runlevel0.target,  poweroff.target

                1  ==>  runlevel1.target,  rescue.target

                2  ==>  runlevel2.tartet,  multi-user.target

                3  ==>  runlevel3.tartet,  multi-user.target

                4  ==>  runlevel4.tartet,  multi-user.target

                5  ==>  runlevel5.target,  graphical.target

                6  ==>  runlevel6.target,  reboot.target

                

            级别切换: init  N  ==>  systemctl  isolate  NAME.target

            

            查看级别: runlevel  ==>  systemctl  list-units  --type  target

            查看所有级别: systemctl  list-units  -t  target  -a

            

            获取默认运行级别:systemctl  get-default  

            修改默认运行级别: systemctl  set-default   NAME.target

            

            切换至紧急救援模式: systemctl  rescue

            切换至emergency模式: systemctl  emergency

            

        其它常用命令:

            关机: systemctl  halt,  systemctl  poweroff

            重启: systemctl  reboot

            挂起: systemctl  suspend

            快照: systemctl  hibernate

            快照并挂起: systemctl  hybrid-sleep

            

        service unit file:

            文件通常由三部分组成:

                [Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等;

                [Service]:与特定类型相关的专用选项;此处为Service类型;

                [Install]:定义由“systemctl  enable”以及"systemctl  disable“命令在实现服务启用或禁用时用到的一些选项;

                

            Unit段的常用选项:

                Description:描述信息; 意义性描述;

                After:定义unit的启动次序;表示当前unit应该晚于哪些unit启动;其功能与Before相反;

                Requies:依赖到的其它units;强依赖,被依赖的units无法激活时,当前unit即无法激活;

                Wants:依赖到的其它units;弱依赖;

                Conflicts:定义units间的冲突关系;

                

            Service段的常用选项:

                Type:用于定义影响ExecStart及相关参数的功能的unit进程启动类型;

                    类型:

                        simple:

                        forking:

                        oneshot:

                        dbus:

                        notify:

                        idle:

                EnvironmentFile:环境配置文件;

                ExecStart:指明启动unit要运行命令或脚本; ExecStartPre, ExecStartPost

                ExecStop:指明停止unit要运行的命令或脚本;

                Restart:

                

            Install段的常用选项:

                Alias:

                RequiredBy:被哪些units所依赖;

                WantedBy:被哪些units所依赖;

                

        注意:对于新创建的unit文件或,修改了的unit文件,要通知systemd重载此配置文件;

            # systemctl  daemon-reload

            

        练习:为当前系统的httpd服务提供一个unit文件;

        

bash脚本编程:

    

    函数、case语言

        case语句:

            case  $VARIABLE  in

            PAT1)

                分支1

                ;;

            PAT2)

                分支2

                ;;

            *)

                分支n

                ;;

            esac

            

            PATTERN: GLOB, |

        

        函数:结构化编程,代码重用;

            function f_name {

                函数体

            }

            

            f_name() {

                函数体

            }

            

            函数定义

            函数调用:给定函数名;

            

            局部变量:local  VARIABLE

        

    数组:

        程序=指令+数据

            指令:

            数据:变量、文件

        

        变量:存储单个元素的内存空间;

        数组:存储多个元素的连续的内存空间;

            数组名:整个数组只有一个名字;

            数组索引:编号从0开始;

                数组    名[索引],

                ${ARRAY_NAME[INDEX]}

                

            注意:bash-4及之后的版本,支持自定义索引格式,而不仅仅是0,1,2,...数字格式;

                此类数组称之为“关联数组”

                

        声明数组:

            declare  -a  NAME:声明索引数组;

            declare  -A  NAME:声明关联数组;

            

        数组中元素的赋值方式:

            (1) 一次只赋值一个元素;

                ARRAY_NAME[INDEX]=value

            (2) 一次赋值全部元素;

                ARRAY_NAME=("VAL1"  "VAL2"  "VAL3"  ...)

            (3) 只赋值特定元素;

                ARRAY_NAME=([0]="VAL1"  [3]="VAL4" ...)

                

                注意:bash支持稀疏格式的数组;

            (4) read  -a  ARRAY_NAME

            

        引用数组中的元素:${ARRAY_NAME[INDEX]}

            注意:引用时,只给数组名,表示引用下标为0的元素;

            

        数组的长度(数组中元素的个数):

            ${#ARRAY_NAME[*]}

            ${#ARRAY_NAME[@]}

            

        示例:生成10个随机数,并找出其中的最大值和最小值;

            #!/bin/bash

            #

            declare -a  rand

            declare -i max=0


            for i in {0..9}; do

                rand[$i]=$RANDOM

                echo ${rand[$i]}

                [ ${rand[$i]} -gt $max ] && max=${rand[$i]}

            done


            echo "MAX: $max"            

            

        练习:生成10个随机数,而后由小到大进行排序;

        

        练习:写一个脚本

            定义一个数组,数组中的元素是/var/log目录下所有以.log结尾的文件;统计其下标为偶数的文件中的行数之和;

            

                #!/bin/bash

                #

                declare -a files

                files=(/var/log/*.log)


                declare -i lines=0


                for i in $(seq 0 $[${#files[*]}-1]); do

                    if [ $[$i%2] -eq 0 ]; then

                        let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1)

                    fi

                done


                echo "Lines: $lines."

                

        引用数组中的所有元素:

            ${ARRAY_NAME[*]}

            ${ARRAY_NAME[@]}

            

            数组元素切片: ${ARRAY_NAME[@]:offset:number}

                offset:要路过的元素个数;

                number:要取出的元素个数;省略number时,表示取偏移量之后的所有元素;

                

        向非稀疏格式数组中追加元素:

            ARRAY_NAME[${#ARRAY_NAME[*]}]=

            

        删除数组中的某元素:

            unset  ARRAY[INDEX]

            

        关联数组:

            declare  -A  ARRAY_NAME

                ARRAY_NAME=([index_name1]="value1"  [index_name2]="value2" ...)

                

    bash的内置字符串处理工具:

        

        字符串切片:

            ${var:offset:number}

                取字符串的子串;

                取字符趾的最右侧的几个字符:${var:  -length}

                    注意:冒号后必须有一个空白字符;

                    

        基于模式取子串:

            ${var#*word}:其中word是指定的分隔符;功能:自左而右,查找var变量所存储的字符串中,第一次出现的word分隔符,删除字符串开头至此分隔符之间的所有字符;

            ${var##*word}:其中word是指定的分隔符;功能:自左而右,查找var变量所存储的字符串中,最后一次出现的word分隔符,删除字符串开头至此分隔符之间的所有字符;

                

                mypath="/etc/init.d/functions"

                ${mypath##*/}:   functions

                ${mypath#*/}:  etc/init.d/functions

                

            ${var%word*}:其中word是指定的分隔符;功能:自右而左,查找var变量所存储的字符串中,第一次出现的word分隔符,删除此分隔符至字符串尾部之间的所有字符;

            ${var%%word*}:其中word是指定的分隔符;功能:自右而左,查找var变量所存储的字符串中,最后一次出现的word分隔符,删除此分隔符至字符串尾部之间的所有字符;

            

                mypath="/etc/init.d/functions"

                ${mypath%/*}:  /etc/init.d

                

                url=http://www.magedu.com:80

                    ${url##*:}

                    ${url%%:*}

                    

        查找替换:

            ${var/PATTERN/SUBSTI}:查找var所表示的字符串中,第一次被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串;

            ${var//PATTERN/SUBSTI}:查找var所表示的字符串中,所有被PATTERN所匹配到的字符串,并将其全部替换为SUBSTI所表示的字符串;

            

            ${var/#PATTERN/SUBSTI}:查找var所表示的字符串中,行首被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串;

            ${var/%PATTERN/SUBSTI}:查找var所表示的字符串中,行尾被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串;

                        

            注意:PATTERN中使用glob风格和通配符;

            

        查找删除:

            ${var/PATTERN}:以PATTERN为模式查找var字符串中第一次的匹配,并删除之;

            ${var//PATERN}

            ${var/#PATTERN}

            ${var/%PATTERN}

            

        字符大小写转换:

            ${var^^}:把var中的所有小写字符转换为大写;

            ${var,,}:把var中的所有大写字符转换为小写;

            

        变量赋值:

            ${var:-VALUE}:如果var变量为空,或未设置,那么返回VALUE;否则,则返回var变量的值;

            ${var:=VALUE}:如果var变量为空,或未设置,那么返回VALUE,并将VALUE赋值给var变量;否则,则返回var变量的值;

            ${var:+VALUE}:如果var变量不空,则返回VALUE;

            ${var:?ERROR_INFO}:如果var为空,或未设置,那么返回ERROR_INFO为错误提示;否则,返回var值;

            

    练习:写一个脚本,完成如下功能

        (1) 提示用户输入一个可执行命令的名称;

        (2) 获取此命令所依赖到的所有库文件列表;

        (3) 复制命令至某目标目录(例如/mnt/sysroot,即把此目录当作根)下的对应的路径中

            bash,  /bin/bash  ==> /mnt/sysroot/bin/bash

            useradd, /usr/sbin/useradd  ==>  /mnt/sysroot/usr/sbin/useradd

        (4) 复制此命令依赖到的所有库文件至目标目录下的对应路径下;

            /lib64/ld-linux-x8664.so.2  ==>  /mnt/sysroot/lib64/ld-linux-x8664.so.2

            

        进一步:

            每次复制完成一个命令后,不要退出,而是提示用户继续输入要复制的其它命令,并重复完成如上所描述的功能;直到用户输入“quit”退出脚本;

            

    

    写一个脚本:

        ping命令去查看172.16.1.1-172.16.67.1范围内的所有主机是否在线;在线的显示为up, 不在线的显示down,分别统计在线主机,及不在线主机数;

        

        分别使用for, while和until循环实现。

        

            #!/bin/bash

            #

            declare -i uphosts=0

            declare -i downhosts=0


            for i in {1..17}; do

                if ping -W 1 -c 1 172.16.$i.1 &> /dev/null; then

                    echo "172.16.$i.1 is up."

                    let uphosts+=1

                else

                    echo "172.16.$i.1 is down."

                    let downhosts+=1

                fi

            done


            echo "Up hosts: $uphosts, Down hosts: $downhosts."        

                        

                    

            #!/bin/bash

            #

            declare -i uphosts=0

            declare -i downhosts=0

            declare -i i=1


            hostping() {

                if ping -W 1 -c 1 $1 &> /dev/null; then

                    echo "$1 is up."

                    return 0

                else

                    echo "$1 is down."

                    return 1

                fi

            }


            while [ $i -le 67 ]; do

                hostping 172.16.$i.1

                [ $? -eq 0 ] && let uphosts++ || let downhosts++

                let i++

            done


            echo "Up hosts: $uphosts, Down hosts: $downhosts."                    

                

    写一个脚本,实现:

        能探测C类、B类或A类网络中的所有主机是否在线;

            

            #!/bin/bash

            #


            cping() {

                local i=1

                while [ $i -le 5 ]; do

                    if ping -W 1 -c 1 $1.$i &> /dev/null; then

                        echo "$1.$i is up"

                    else

                        echo "$1.$i is down."

                    fi

                    let i++

                done

            }


            bping() {

                local j=0

                while [ $j -le 5 ]; do

                    cping $1.$j

                    let j++

                done

            }


            aping() {

                local x=0

                while [ $x -le 255 ]; do

                    bping $1.$x

                    let x++

                done

            }

            

        提示用户输入一个IP地址或网络地址;获取其网络,并扫描其网段;

        

    信号捕捉:

        列出信号:

            trap  -l

            kill  -l

            man  7  signal

        

            trap  'COMMAND'  SIGNALS

            

            常可以进行捕捉的信号:

                HUP, INT

            

            示例:

                #!/bin/bash

                #

                declare -a hosttmpfiles

                trap  'mytrap'  INT


                mytrap()  {

                    echo "Quit"

                    rm -f ${hosttmpfiles[@]}

                    exit 1

                }



                for i in {1..50}; do

                    tmpfile=$(mktemp /tmp/ping.XXXXXX)

                    if ping -W 1 -c 1 172.16.$i.1 &> /dev/null; then

                        echo "172.16.$i.1 is up" | tee $tmpfile

                    else

                        echo "172.16.$i.1 is down" | tee $tmpfile

                    fi

                    hosttmpfiles[${#hosttmpfiles[*]}]=$tmpfile

                done


                rm -f ${hosttmpfiles[@]}

                

    在bash中使用ACSII颜色

        \033[31m hello \033[0m

            ##m:

                左侧#:

                    3:前景色

                    4:背景色

                右侧#:颜色种类

                    1, 2, 3, 4, 5, 6, 7

            

            #m:

                加粗、闪烁等功能;

                

            多种控制符,可组合使用,彼此间用分号隔开;

            

    dialog命令可实现窗口化编程;

        各窗体控件使用方式;

        如何获取用户选择或键入的内容?

            默认,其输出信息被定向到了错误输出流;

        

    《高级bash编程指南》,《Linux命令行和shell脚本编程宝典》

                    

                

回顾:bash脚本编程数组


    数组,字符串处理


    数组:

        数组:declare -a

            index: 0-

        关联数组: declare -A


    字符串处理:

        切片、查找替换、查找删除、变量赋值


GNU awk:

    

    文本处理三工具:grep, sed, awk

        grep, egrep, fgrep:文本过滤工具;pattern

        sed: 行编辑器

            模式空间、保持空间

        awk:报告生成器,格式化文本输出;


        AWK: Aho, Weinberger, Kernighan --> New AWK, NAWK


        GNU awk, gawk


    gawk - pattern scanning and processing language


        基本用法:gawk [options] 'program' FILE ...

            program: PATTERN{ACTION STATEMENTS}

                语句之间用分号分隔


                print, printf


            选项:

                -F:指明输入时用到的字段分隔符;

                -v var=value: 自定义变量;


        1、print


            print item1, item2, ...


            要点:

                (1) 逗号分隔符;

                (2) 输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式;

                (3) 如省略item,相当于print $0;


        2、变量

            2.1 内建变量

                FS:input field seperator,默认为空白字符;

                OFS:output field seperator,默认为空白字符;

                RS:input record seperator,输入时的换行符;

                ORS:output record seperator,输出时的换行符;


                NF:number of field,字段数量

                    {print NF}, {print $NF}

                NR:number of record, 行数;

                FNR:各文件分别计数;行数;


                FILENAME:当前文件名;


                ARGC:命令行参数的个数;

                ARGV:数组,保存的是命令行所给定的各参数;


            2.2 自定义变量

                (1) -v var=value


                    变量名区分字符大小写;


                (2) 在program中直接定义


        3、printf命令


            格式化输出:printf FORMAT, item1, item2, ...


                (1) FORMAT必须给出;

                (2) 不会自动换行,需要显式给出换行控制符,\n

                (3) FORMAT中需要分别为后面的每个item指定一个格式化符号;


                格式符:

                    %c: 显示字符的ASCII码;

                    %d, %i: 显示十进制整数;

                    %e, %E: 科学计数法数值显示;

                    %f:显示为浮点数;

                    %g, %G:以科学计数法或浮点形式显示数值;

                    %s:显示字符串;

                    %u:无符号整数;

                    %%: 显示%自身;


                修饰符:

                    #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度;

                        %3.1f

                    -: 左对齐

                    +:显示数值的符号


        4、操作符


            算术操作符:

                x+y, x-y, x*y, x/y, x^y, x%y

                -x

                +x: 转换为数值;


            字符串操作符:没有符号的操作符,字符串连接


            赋值操作符:

                =, +=, -=, *=, /=, %=, ^=

                ++, --


            比较操作符:

                >, >=, <, <=, !=, ==


            模式匹配符:

                ~:是否匹配

                !~:是否不匹配


            逻辑操作符:

                &&

                ||

                !


            函数调用:

                function_name(argu1, argu2, ...)


            条件表达式:

                selector?if-true-expression:if-false-expression


                # awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd


        5、PATTERN


            (1) empty:空模式,匹配每一行;

            (2) /regular expression/:仅处理能够被此处的模式匹配到的行;

            (3) relational expression: 关系表达式;结果有“真”有“假”;结果为“真”才会被处理;

                真:结果为非0值,非空字符串;

            (4) line ranges:行范围,

                startline,endline:/pat1/,/pat2/


                注意: 不支持直接给出数字的格式

                ~]# awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd

            (5) BEGIN/END模式

                BEGIN{}: 仅在开始处理文件中的文本之前执行一次;

                END{}:仅在文本处理完成之后执行一次;


        6、常用的action


            (1) Expressions

            (2) Control statements:if, while等;

            (3) Compound statements:组合语句;

            (4) input statements

            (5) output statements


        7、控制语句


            if(condition) {statments}

            if(condition) {statments} else {statements}

            while(conditon) {statments}

            do {statements} while(condition)

            for(expr1;expr2;expr3) {statements}

            break

            continue

            delete array[index]

            delete array

            exit

            { statements }


            7.1 if-else


                语法:if(condition) statement [else statement]


                ~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd


                ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd


                ~]# awk '{if(NF>5) print $0}' /etc/fstab


                ~]# df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}'


                使用场景:对awk取得的整行或某个字段做条件判断;


            7.2 while循环

                语法:while(condition) statement

                    条件“真”,进入循环;条件“假”,退出循环;


                使用场景:对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用;


                ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg


                ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg


            7.3 do-while循环

                语法:do statement while(condition)

                    意义:至少执行一次循环体


            7.4 for循环

                语法:for(expr1;expr2;expr3) statement


                    for(variable assignment;condition;iteration process) {for-body}


                ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg


                特殊用法:

                    能够遍历数组中的元素;

                        语法:for(var in array) {for-body}


            7.5 switch语句

                语法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; ...; default: statement}


            7.6 break和continue

                break [n]

                continue


            7.7 next


                提前结束对本行的处理而直接进入下一行;


                ~]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd


        8、array


            关联数组:array[index-expression]


                index-expression:

                    (1) 可使用任意字符串;字符串要使用双引号;

                    (2) 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”;


                    若要判断数组中是否存在某元素,要使用"index in array"格式进行;


                    weekdays[mon]="Monday"


                若要遍历数组中的每个元素,要使用for循环;

                    for(var in array) {for-body}


                    ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'


                    注意:var会遍历array的每个索引;

                    state["LISTEN"]++

                    state["ESTABLISHED"]++


                    ~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'


                    ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log


                    练习1:统计/etc/fstab文件中每个文件系统类型出现的次数;

                    ~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab


                    练习2:统计指定文件中每个单词出现的次数;

                    ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab


        9、函数


            9.1 内置函数

                数值处理:

                    rand():返回0和1之间一个随机数;


                字符串处理:

                    length([s]):返回指定字符串的长度;

                    sub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其第一次出现替换为s所表示的内容;

                    gsub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其所有出现均替换为s所表示的内容;


                    split(s,a[,r]):以r为分隔符切割字符s,并将切割后的结果保存至a所表示的数组中;


                    ~]# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'


            9.2 自定义函数


                《sed和awk》























文档更新时间: 2019-12-22 09:49   作者:老王