美文网首页
Chapter 8——systemd新特性和awk命令

Chapter 8——systemd新特性和awk命令

作者: xlong1121 | 来源:发表于2018-10-19 00:27 被阅读0次

    一、简述systemd的新特性及unit常见类型分析,能够实现编译安装的如nginx\apache实现通过systemd来管理

    1、systemd新特性及unit常见类型分析

    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
    

    2、实现systemd管理nginx/apache

    第一步:首先下载nginx源码包并编译安装

    [root@localhost ~]# wget https://nginx.org/download/nginx-1.15.5.tar.gz
    --2018-10-18 10:00:33--  https://nginx.org/download/nginx-1.15.5.tar.gz
    Resolving nginx.org (nginx.org)... 206.251.255.63, 95.211.80.227, 2001:1af8:4060:a004:21::e3, ...
    Connecting to nginx.org (nginx.org)|206.251.255.63|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 1024791 (1001K) [application/octet-stream]
    Saving to: ‘nginx-1.15.5.tar.gz’
    
    100%[=======================================================================================================================================================================>] 1,024,791   96.0KB/s   in 11s    
    
    2018-10-18 10:00:49 (92.0 KB/s) - ‘nginx-1.15.5.tar.gz’ saved [1024791/1024791]
    
    [root@localhost ~]# tar zxf nginx-1.15.5.tar.gz 
    [root@localhost ~]# cd nginx-1.15.5
    [root@localhost nginx-1.15.5]# ls
    auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  man  README  src
    [root@localhost nginx-1.15.5]# ./configure --prefix=/usr/local/nginx
    checking for OS
     + Linux 3.10.0-327.el7.x86_64 x86_64
    checking for C compiler ... found
     + using GNU C compiler
     + gcc version: 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) 
    checking for gcc -pipe switch ... found
    ......
    checking for -Wl,-E switch ... found
    checking for gcc builtin atomic operations ... found
    checking for zlib library ... found
    creating objs/Makefile
    
    Configuration summary
      + using system PCRE library
      + OpenSSL library is not used
      + using system zlib library
    
      nginx path prefix: "/usr/local/nginx"
      nginx binary file: "/usr/local/nginx/sbin/nginx"
      nginx modules path: "/usr/local/nginx/modules"
      nginx configuration prefix: "/usr/local/nginx/conf"
      nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
      nginx pid file: "/usr/local/nginx/logs/nginx.pid"
      nginx error log file: "/usr/local/nginx/logs/error.log"
      nginx http access log file: "/usr/local/nginx/logs/access.log"
      nginx http client request body temporary files: "client_body_temp"
      nginx http proxy temporary files: "proxy_temp"
      nginx http fastcgi temporary files: "fastcgi_temp"
      nginx http uwsgi temporary files: "uwsgi_temp"
      nginx http scgi temporary files: "scgi_temp"
    [root@localhost nginx-1.15.5]# make && make install
    make -f objs/Makefile
    make[1]: Entering directory `/root/nginx-1.15.5'
    cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        -o objs/src/core/nginx.o \
        src/core/nginx.c
    cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        -o objs/src/core/ngx_log.o \
    ......
    cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf.default'
    test -d '/usr/local/nginx/logs' \
        || mkdir -p '/usr/local/nginx/logs'
    test -d '/usr/local/nginx/logs' \
        || mkdir -p '/usr/local/nginx/logs'
    test -d '/usr/local/nginx/html' \
        || cp -R html '/usr/local/nginx'
    test -d '/usr/local/nginx/logs' \
        || mkdir -p '/usr/local/nginx/logs'
    make[1]: Leaving directory `/root/nginx-1.15.5'
    [root@localhost nginx-1.15.5]# 
    

    第二步:确认nginx安装成功,且正常提供服务
    测试启动nginx服务

    [root@localhost ~]# /usr/local/nginx/sbin/nginx
    [root@localhost ~]# ss -tan 
    State       Recv-Q Send-Q                                                           Local Address:Port                                                                          Peer Address:Port              
    LISTEN      0      128                                                                          *:80                                                                                       *:* 
    LISTEN      0      128                                                                          *:22                                                                                       *:*                  
    LISTEN      0      100                                                                  127.0.0.1:25                                                                                       *:*                  
    ESTAB       0      52                                                               192.168.0.131:22                                                                             192.168.0.1:60069              
    LISTEN      0      128                                                                         :::22                                                                                      :::*                  
    LISTEN      0      100                                                                        ::1:25                                                                                      :::* 
    

    此时可通过服务器IP地址,访问到nginx欢迎页面,说明nginx安装成功,且正常提供服务


    image.png

    第三步:创建unit文件
    由于nginx属于服务类unit,故unit文件类型以.service结尾

    [root@localhost ~]# cd /usr/lib/systemd/system
    [root@localhost system]# cat  << EOF  >> nginx.service
    > [unit]
    > Desciption=This is a web service
    > After=network.target
    > 
    > [Service]
    > Type=forking
    > ExecStart=/usr/local/nginx/sbin/nginx
    > ExecStop=/usr/local/nginx/sbin/nginx -s stop
    > ExecReload=/usr/local/nginx/sbin/nginx -s reload
    > 
    > [Install]
    > WantedBy=multi-user.target
    > EOF
    

    第四步:systemd重载此配置文件

    [root@localhost system]# systemctl daemon-reload
    

    最后:测试systemctl的管理效果

    [root@localhost system]# /usr/local/nginx/sbin/nginx -s stop
    [root@localhost system]# ss -tan
    State      Recv-Q Send-Q              Local Address:Port                             Peer Address:Port              
    LISTEN     0      128                             *:22                                          *:*                  
    LISTEN     0      100                     127.0.0.1:25                                          *:*                  
    ESTAB      0      52                  192.168.0.131:22                                192.168.0.1:60069              
    LISTEN     0      128                            :::22                                         :::*                  
    LISTEN     0      100                           ::1:25                                         :::*
    
    image.png
    [root@localhost system]# systemctl start nginx
    [root@localhost system]# ss -tan
    State      Recv-Q Send-Q              Local Address:Port                             Peer Address:Port              
    LISTEN     0      128                             *:80                                          *:*                  
    LISTEN     0      128                             *:22                                          *:*                  
    LISTEN     0      100                     127.0.0.1:25                                          *:*                  
    ESTAB      0      52                  192.168.0.131:22                                192.168.0.1:60069              
    SYN-SENT   0      1                   192.168.0.131:47014                         192.168.204.129:8090               
    SYN-SENT   0      1                   192.168.0.131:55349                         192.168.204.129:8080               
    LISTEN     0      128                            :::22                                         :::*                  
    LISTEN     0      100                           ::1:25                                         :::*
    
    image.png

    二、描述awk命令用法及示例(至少3例)

    awk命令

    基本用法:awk [options] 'program' FILE ...
        program:PATTERN{ACTION STATEMENTS}
            语句之间用分号分隔
        options:
            -F:指明输入时用到的字段分隔符;
            -v var=value:自定义变量;
    
    常见用法1——print
    print item1,item2,...
    要点:
        (1)逗号分隔符;
        (2)输出的各item可以是字符串,也可以是数值;当前记录的字段、变量或awk的表达式;
        (3)如省略item,相当于print $0,即打印整行;
    

    示例:打印当前系统的用户名和其所用shell

    [root@localhost system]# awk -F: '{print $1,"\t",$7}' /etc/passwd
    root     /bin/bash
    bin      /sbin/nologin
    daemon   /sbin/nologin
    adm      /sbin/nologin
    lp   /sbin/nologin
    sync     /bin/sync
    shutdown     /sbin/shutdown
    halt     /sbin/halt
    mail     /sbin/nologin
    operator     /sbin/nologin
    games    /sbin/nologin
    ftp      /sbin/nologin
    nobody   /sbin/nologin
    avahi-autoipd    /sbin/nologin
    systemd-bus-proxy    /sbin/nologin
    systemd-network      /sbin/nologin
    dbus     /sbin/nologin
    polkitd      /sbin/nologin
    tss      /sbin/nologin
    postfix      /sbin/nologin
    sshd     /sbin/nologin
    
    常见用法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}:打印每段的字段数量;$NF:最后一个字段
            *注:awk中引用变量时不加$,引用字段才用$
        NR:number of record,行数
        FNR:行数,各文件分别计数
        
        FILENAME:当前文件名;
    
        ARGC:命令行参数的个数;
        ARGV:数组,保存的是命令行所给定的各参数;
    
    2.2 自定义变量
        (1)-v var=value
            变量名区分字符大小写;
        (2)在program中直接定义
    

    示例:打印当前系统的用户名和其所用shell,中间使用###分隔

    [root@localhost system]# awk -v FS=':' -v OFS='###' '{print $1,$7}' /etc/passwd
    root###/bin/bash
    bin###/sbin/nologin
    daemon###/sbin/nologin
    adm###/sbin/nologin
    lp###/sbin/nologin
    sync###/bin/sync
    shutdown###/sbin/shutdown
    halt###/sbin/halt
    mail###/sbin/nologin
    operator###/sbin/nologin
    games###/sbin/nologin
    ftp###/sbin/nologin
    nobody###/sbin/nologin
    avahi-autoipd###/sbin/nologin
    systemd-bus-proxy###/sbin/nologin
    systemd-network###/sbin/nologin
    dbus###/sbin/nologin
    polkitd###/sbin/nologin
    tss###/sbin/nologin
    postfix###/sbin/nologin
    sshd###/sbin/nologin
    
    常见用法3——printf命令
          格式化输出:printf FROMAT,item1,item2,...
            (1)FORMAT必须要给出;
            (2)不会自动换行,需要显式给出换行控制符,\n;
            (3)FORMAT中需要分别为后面的每个item指定一个格式化符号;
    
            格式符:
                %c:显示字符的ASCII码;
                %d,%i:显示十进制整数;
                %e,%E:科学计数法数值显示;
                %f:显示为浮点数;
                %g,%G:以科学计数法或浮点形式显示数值;
                %s:显示字符串;
                %u:无符号整数;
                %%:显示%本身;   
    
            修饰符:
                #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度;
                    %3.1f
                -:左对齐(默认为右对齐)
                +:显示数值的符号(即正负,+、-)
    

    示例1:格式化输出当前系统的用户名和UID

    [root@localhost system]# awk -F: '{printf "Username: %s,UID: %d\n",$1,$3}' /etc/passwd
    Username: root,UID: 0
    Username: bin,UID: 1
    Username: daemon,UID: 2
    Username: adm,UID: 3
    Username: lp,UID: 4
    Username: sync,UID: 5
    Username: shutdown,UID: 6
    Username: halt,UID: 7
    Username: mail,UID: 8
    Username: operator,UID: 11
    Username: games,UID: 12
    Username: ftp,UID: 14
    Username: nobody,UID: 99
    Username: avahi-autoipd,UID: 170
    Username: systemd-bus-proxy,UID: 999
    Username: systemd-network,UID: 998
    Username: dbus,UID: 81
    Username: polkitd,UID: 997
    Username: tss,UID: 59
    Username: postfix,UID: 89
    Username: sshd,UID: 74      
    

    示例2:左对齐的格式化输出

    [root@localhost system]# awk -F: '{printf "Username: %-20s,UID: %d\n",$1,$3}' /etc/passwd
    Username: root                ,UID: 0
    Username: bin                 ,UID: 1
    Username: daemon              ,UID: 2
    Username: adm                 ,UID: 3
    Username: lp                  ,UID: 4
    Username: sync                ,UID: 5
    Username: shutdown            ,UID: 6
    Username: halt                ,UID: 7
    Username: mail                ,UID: 8
    Username: operator            ,UID: 11
    Username: games               ,UID: 12
    Username: ftp                 ,UID: 14
    Username: nobody              ,UID: 99
    Username: avahi-autoipd       ,UID: 170
    Username: systemd-bus-proxy   ,UID: 999
    Username: systemd-network     ,UID: 998
    Username: dbus                ,UID: 81
    Username: polkitd             ,UID: 997
    Username: tss                 ,UID: 59
    Username: postfix             ,UID: 89
    Username: sshd                ,UID: 74
    
    常见用法4——PATTERN(模式匹配)
        (1)empty:空模式,匹配每一行;
        (2)/regular expression/:仅处理能够被此处的模式匹配到的行
        (3)relational expression:关系表达式;结果有“真”有“假”;结果为“真”才会被处理;
            真:结果为非0值,非空字符串;
        (4)line ranges:行范围
            starline,endline:/pat1/,/pat2/
            注意:不支持直接给出数字的格式
         (5)BEGIN/END模式
            BEGIN{}:仅在开始处理文件中的文本之前执行一次;
            END{}:仅在文本处理完成之后执行一次;
    

    示例:显示默认shell为bash的用户

    [root@localhost ~]# awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
    root /bin/bash
    或
    [root@localhost ~]# awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd
    root /bin/bash
    
    常见用法5——控制语句
    5.1 if-else
        语法:if(condition) statement [else statement]
    
        示例:
        awk -F: '{if($3>=1000) print $1,$3}' /etc/passwd
        awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or sysadmin: %s\n",$1}}'
    
        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取得的整行或某个字段做条件判断;
    
    5.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
    
    5.3 do-while循环
        语法:do statement while(condition)
            意义:至少执行一次循环体
    
    5.4 for循环
        语法:for(expr1;expr2;expr3)statement
            for (variable assighment;condition;iteration process) {for-body}
    
        示例:
        awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){print $i,length($1)}}' /etc/grub2.cfg
    
        特殊用法:
            能够遍历数组中的元素:
                语法:for(var in array) {for-body}
    
    5.5 switch语句
        语法:switch(expression) {case VALUE1 or /REGEXP/: statement;case VALUE2 or /REGEXP2/: statement;...;default: statement}
    
    5.6 break和continue
        break [n]
        continue
    
    5.7 next
        提前结束对本行的处理而直接进入下一行;
    
        awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
    
    常见用法6——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
    

    实用示例:统计/etc/fstab文件中以UUID开头的行文件系统类型出现的次数

    [root@localhost ~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab
    xfs 1
    

    三、描述awk函数示例(至少3例)

    内置函数

        数值处理:
            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所表示的数组中;
    

    示例1:全局替换字符串并打印

    [root@localhost ~]# awk -F: 'gsub("/sbin/nologin","/bin/false"){print $1,$7}' /etc/passwd
    bin /bin/false
    daemon /bin/false
    adm /bin/false
    lp /bin/false
    mail /bin/false
    operator /bin/false
    games /bin/false
    ftp /bin/false
    nobody /bin/false
    avahi-autoipd /bin/false
    systemd-bus-proxy /bin/false
    systemd-network /bin/false
    dbus /bin/false
    polkitd /bin/false
    tss /bin/false
    postfix /bin/false
    sshd /bin/false
    

    示例2:打印长度为4字符的用户名

    [root@localhost ~]# awk -F: 'length($1)==4{print $1}' /etc/passwd
    root
    sync
    halt
    mail
    dbus
    sshd
    

    示例3:打印当前系统建立了的TCP连接的IP地址及数量

    [root@localhost ~]# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'
    192.168.0.1 1
    0.0.0.0 3
    

    相关文章

      网友评论

          本文标题:Chapter 8——systemd新特性和awk命令

          本文链接:https://www.haomeiwen.com/subject/xzqezftx.html