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

一、简述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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容