简述systemd和unit,以及awk命令函数示例

简述systemd

System的新特性

  • 系统引导时实现服务并行启动
  • 按需激活进程
  • 系统状态快照
  • 基于依赖关系定义服务控制逻辑

System 核心概念: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文件;
systemctl命令:
control the systemd system and service manger
语法systemctl [OPTIONS...] COMMAND [NAME...]

  • 启动:systemctl start NAME.service
  • 停止:systemctl stop NAME.service
  • 重启:systemctl restart NAME.service
  • 状态:systemctl status NAME.service
  • 条件式重启:systemctl try-restart NAME.service
  • 重载或重启服务:systemctl reload-or-restart NAME.service
  • 重载或条件式重启:systemctl reload-or-try-restart NAME.service
  • 查看某服务当前激活与否的状态:systemctl is-active NAME.service
  • 查看所有已激活的服务:systemctl list-units –type service
  • 查看所有服务(已激活及未激活)systemctl list-units -t service –all
  • 设置服务开机自启:systemctl enable NAME.service
  • 禁止服务开机自启:systemctl disable NAME.service
  • 查看某服务是否设定为开机自启:systemtl is-enabled NAME.service
  • 禁止某服务设定为开机自启:systemctl mask NAME.service
  • 取消此禁止:systemctl unmask NAME.service
  • 查看服务的依赖关系: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
  • 级别切换:systemctl isolate NAME.target

  • 查看级别:systemctl list-units –type target

  • 查看所有级别:systemctl list-units –type 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
  • 文件通常由三部分组成:

    1. [Unit]:定义与unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系
    2. [Service]:与特定类型相关的专用选项;此处为service类型
    3. [Install]:定义由“systemctl enable”以及“systemctl disable”命令在实现服务;启用或禁用时用到的一些选项
  • Unit段的常用选项:

    • Description :描述信息;意义性描述
    • After :定义unit的启动次序,表示当前unit应该晚于哪些unit启动;其功能与Before相反
    • Requies :依赖到其它unit,强依赖;被依赖的unit无法激活时,当前unit即无法激活
    • Wants:依赖到其它units,弱依赖;被依赖的unit无法激活时,当前unit可以激活
    • Conflicts:定义units间的冲突关系
  • Service 段的常用选项:

    • Type:用于定义影响ExecStart及相关参数的功能的unit进程启动的类型

      • 类型:

        • simple
        • forking
        • oneshot
        • dbus
        • notify
        • idle
    • EnvironmentFile:环境配置文件

    • ExecStart:指明启动unit要运行命令或脚本

      • ExecStartPre:预启动
      • ExecStartPost:后启动
    • ExecStop:指明停止unit要运行的命令或脚本

    • Restart:重启unit要运行的命令或脚本

  • Install段的常用选项:

    • Alias:别名
    • RequiredBy:被哪些units所依赖
    • WanteBy:被哪些units所依赖
  • **注意:对于新创建的unit文件系统或修改了的unit文件要通知systemd重载此配置文件 systemctl daemon-reload

编译安装如httpd实现通过systemd来管理

#编译apache2.2,htttpd服务的过程如下:
[root@localhost ~]# cd httpd-2.2.32/    
[root@localhost ~]# ./configure --prefix=/usr/local/apache2 --sysconfdir=/etc/httpd2 
[root@localhost ~]# make
[root@localhost ~]# make install 
#安装后配置
[root@localhost ~]# vim /etc/profile.d/httpd2.sh
             export PATH=$PATH:/usr/local/apache2/bin
[root@localhost ~]# source /etc/profile.d/httpd2.sh
[root@localhost ~]# vim /etc/ld.so.conf.d/httpd.conf
            /usr/local/apache2/lib
[root@localhost ~]# ldconfig -v
[root@localhost ~]# ln -sv /usr/local/apache2/include/ /usr/include/
[root@localhost ~]# vim /etc/man_db.conf 
#编辑httpd的unit文件
vim /usr/lib/systemd/system/httpd.service

    [Unit]
    Description=The httpd service
    After=network.target

    [Service]
    Type=forking
    ExecStart=/usr/local/apache2/bin/apachectl start
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/usr/local/apache2/bin/apachectl stop
    Restart=/usr/local/apache2/bin/apachectl restart

    [Install]
    WantedBy=multi-user.target

#编辑完成后通知systemd重载此配置
    systemctl daemon-reload
#启动服务
    systemctl start httpd.service
#查看服务是否启动
    ss -tan  80端口是在监听状态,服务启动成功
#停止服务
    systemctl stop httpd.service
#查看状态
    systemctl status httpd.service
      active (running)  正在运行OK

编译安装如nginx实现通过systemd来管理

     ./configure --prefix=/usr/local/nginx
     #编译后报错error提示需要PCRE库
     wget http://mirrors.163.com/centos/7/os/x86_64/Packages/pcre-8.32-17.el7.x86_64.rpm
     rpm -ivh pcre-8.32-17.el7.x86_64.rpm
     wget http://mirrors.163.com/centos/7/os/x86_64/Packages/pcre-devel-8.32-17.el7.x86_64.rpm
     rpm -ivh pcre-devel-8.32-17.el7.x86_64.rpm 
     ./configure --prefix=/usr/local/nginx
     #编译后报错error提示需要zlib库
     wget http://mirrors.163.com/centos/7/os/x86_64/Packages/zlib-1.2.7-17.el7.x86_64.rpm
    rpm -ivh zlib-1.2.7-17.el7.x86_64.rpm 
    #依赖的库pcre和zlib安装完成后就可以编译安装nginx
    ./configure --prefix=/usr/local/nginx
    make && make install
    #安装完成后配置环境变量
    vim /etc/profile.d/nginx.sh
        export PATH=$PATH:/usr/local/nginx/sbin
    #安装完成后添加unit文件
    vim /usr/lib/systemd/system/nginx.service
        [Unit]
        Description=this is nginx service
        After=network.target
        [Service]
        Type=forking
        ExecStart=/usr/local/nginx/sbin/nginx
        ExecStop=/usr/local/nginx/sbin/nginx -s stop
        Restart=/usr/local/nginx/sbin/nginx -s reload

        [Install]
        WanteBy=multi-user.target

    #安装完成后启动
        systemctl start nginx.service
        ss -tan
    #观察到80端口LISTEN,启动成功;外部浏览器访问如图

简述systemd和unit,以及awk命令函数示例_第1张图片
nginx.png

GUN awk命令

文本处理三剑客:

  • grep、egrep、fgrep:文本过滤工具
  • sed:行编辑器
  • awk:报表、报告生成器,格式化文本输出

GNU awk简称为gawk,我们通常统称为awk

基本用法:gawk [options] 'program' FILE...
  • program:PATTERN{ACTION STATEMENTS}
选项:
-F:指明输入时用到的字段分隔符
-v var=value:自定义变量

示例:
            [root@localhost ~]# tail -5 /etc/fstab
            #
            /dev/mapper/centos-root /                       xfs     defaults        0 0
            UUID=55bb7b0d-eb2d-454e-aaaa-fcbf3b0bedcd /boot                   xfs     defaults        0 0
            UUID=224da14b-890b-4f1a-8340-5a3ccc016085 /home                   xfs     defaults        0 0
            UUID=0a8f2cdd-14bd-4df1-b23a-078f513ad814 swap                    swap    defaults        0 0
            [root@localhost ~]# tail -5 /etc/fstab|awk ' {print $2,$4}'   
            / defaults
            /boot defaults
            /home defaults
            swap defaults

输出命令
  1. print:print item1,item2,...

    • 要点:<1> 逗号分割符;<2> 输出的各item可以是字符串,也可以是数值、当前变量的字段、变量或awk的表达式;<3> 如果省略item,则默认显示$0,整行
  2. 变量
    2.1 内建变量:
    FS input field sepperator,默认为空白字符
    OFS:output field seperator,默认为空白字符;
    示例:[root@localhost ~]# awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd
    RS:input record seperator,输入时的换行符;
    ORS:output record seperator,输出时的换行符;
    NF:number of field,字段数量
    {print NF}, {print $NF}
    NR:number of record, 行数;

示例:[root@localhost ~]# awk  '{print NR}' /etc/fstab /etc/issue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #显示两个文件总行数

FNR:各文件分别计数;行数;
FILENAME:当前文件名;
ARGC:命令行参数的个数;
ARGV:数组,保存的是命令行所给定的各参数;

    示例:
    [root@localhost ~]# awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue
    3
    [root@localhost ~]# awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue
    awk
    [root@localhost ~]# awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue
    /etc/fstab
    [root@localhost ~]# awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue
    /etc/issue

2.2 自定义变量
<1> -v var=value:变量名区分大小写

例:[root@localhost ~]# awk -v test='hello word' 'BEGIN{print test}'
    hello word

<2> 在program中直接定义

例:[root@localhost ~]# awk 'BEGIN{test="hello word";print test}'
hello word

  1. printf命令:

    • 格式化输出:printf FORMAT, item1,item2,...

    • 要点:
      <1> FORMAT必须给出;
      <2> 不会自动换行,需要显式给出换行控制符\n;
      <3> FORMAT中需要分别为后面的每一个item指定一个格式化符号

    • 格式符:
      %c:显示字符ASCII码
      %d,%i:显示十进制整数
      %e,%E:科学计数法数值显示
      %f:显示浮点数
      %g,%G:以科学计数法或浮点形式显示数值
      %s:显示字符串
      %u:无符号整数
      %%:显示%自身

    • 修饰符:
      <1>#.[#]:第一个数字控制显示的宽度,第二个#标识小数点之后的精度
      <2>-:左对齐;默认为右对齐
      <3>+:显示数值的符号

示例:
[root@localhost ~]# awk -F: ' {printf "Username:%s, Uid:%d \n", $1,$3}' /etc/passwd
[root@localhost ~]# awk -F: ' {printf "Username:%-15s,UId:%d\n", $1,$3}' /etc/passwd

  1. 操作符

    • 算数操作符:x+y,x-y,x*y,x/y,x^y,x%y,-x,+x
    • 字符串操作符:没有符号的操作符,字符串连接
    • 赋值操作符:=,+=,-=,*=,/=,%=,^=,++,–
    • 比较操作符:>,>=,<,<=,!=,==
    • 模式匹配符:是否匹配;!是否不匹配
    • 逻辑操作符:&&,||,!
    • 函数调用:function_name();
    • 传递参数:function_name(argu1,argu2,…)
    • 条件表达式:selector?if-true-expression:if-false-expression
示例:[root@localhost ~]# awk -F: ' {$3>=100?usertype="Common User":usertype="Sysadmin or Sysuser";printf "%15s,%-s\n",$1,usertype}' /etc/passwd
           root,Sysadmin or Sysuser
            bin,Sysadmin or Sysuser
         daemon,Sysadmin or Sysuser

  1. PATTERN
    <1>空模式 empty:匹配文件每一行
    <2>/regular expression/:仅处理能被此处的模式匹配到的行
    <3>relational expression:关系表达式,结果有真有假;结果为真才会被处理;结果为非0值,非空字符串时为真。
    <4>line ranges:行范围 /pat1/,/pat2/ - 注意:此处不支持直接给出数字的格式
    <5> BEGIN/END模式
    • BEGIN{}:仅在开始处理文件中的文本之前执行一次;
    • END{}:仅在文本处理完成之后执行一次;
示例 1:[root@localhost ~]# awk ' /^UUID/{print $1}' /etc/fstab
        UUID=55bb7b0d-eb2d-454e-aaaa-fcbf3b0bedcd
        UUID=224da14b-890b-4f1a-8340-5a3ccc016085
        UUID=0a8f2cdd-14bd-4df1-b23a-078f513ad814

示例 2: [root@localhost ~]# awk -F: '$3>=1000{print $1,$3}' /etc/passwd
        nfsnobody 65534
        inspur 1000

示例 3: [root@localhost ~]# awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
        root /bin/bash
        inspur /bin/bash
        [root@localhost ~]# awk -F: '$NF~"/bin/bash$"{print $1,$NF}' /etc/passwd
        root /bin/bash
        inspur /bin/bash
示例 4:[root@localhost ~]# awk -F: '/^d/,/^a/{print $1,$3}' /etc/passwd
        daemon 2
        adm 3
        dbus 81
        polkitd 999
        abrt 173
示例 5:[root@localhost ~]# awk -F: 'BEGIN{print " username      uid\n=========================="} {print $1,$3}END{print "=========\n end"}' /etc/passwd
         username      uid
        ==========================
        root 0
        bin 1
        daemon 2
        adm 3
        lp 4
        =========
         end

  1. 常用的ACTION
    <1> Expressions
    <2> Control statements
    <3> Compound Statements
    <4> Input statements
    <5> Output statements

  2. 控制语句
    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取得的整行或某个字段做条件判断

    示例1:       
        #如果用户的shell为bash,那么显示此用户
        [root@localhost ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
        root
        inspur
    示例2  #如某一行的字段大于5个,则显示,否则不显示
        [root@localhost ~]# awk ' {if(NF>=5)print $0}' /etc/fstab
        # Created by anaconda on Sun Jul  1 06:20:58 2018
        # Accessible filesystems, by reference, are maintained under '/dev/disk'
        # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
        /dev/mapper/centos-root /                       xfs     defaults        0 0
        UUID=55bb7b0d-eb2d-454e-aaaa-fcbf3b0bedcd /boot                   xfs     defaults        0 0
        UUID=224da14b-890b-4f1a-8340-5a3ccc016085 /home                   xfs     defaults        0 0
        UUID=0a8f2cdd-14bd-4df1-b23a-078f513ad814 swap                    swap    defaults        0 0

    示例3:#使用空间比例大于10%,则显示
        [root@localhost ~]# df -h | awk -F[%] '{print $1}'| awk ' {if($NF>10)print $1}'
文件系统
        /dev/mapper/centos-root
        /dev/sda1

7.2 while循环
语法:while(condition) statement
条件为真进入循环;条件为假退出循环
使用场景:对一行内的多个字段逐一类似处理时使用,对数组中的个元素逐一处理时使用;对每一行的个各字段格式化处理

示例:# /etc/grub2.cfg文件中linux16开头的行统计每一行字段的字符个数,并把大于7个字段的显示出来
    [root@localhost ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){if(length($i)>=7){print $i,length($i)};i++}}' /etc/grub2.cfg 
    linux16 7
    /vmlinuz-3.10.0-693.el7.x86_64 30
    root=/dev/mapper/centos-root 28
    crashkernel=auto 16
    rd.lvm.lv=centos/root 21
    LANG=zh_CN.UTF-8 16
    linux16 7
    /vmlinuz-0-rescue-8e4ba67d04f640d3a12dad38e3d4093b 50
    root=/dev/mapper/centos-root 28
    crashkernel=auto 16
    rd.lvm.lv=centos/root 21

7.3 do-while循环
语法:do statement while(condition)
意义在于至少执行一次

7.4 for循环
语法:for(expr1;expr2;expr) statement

for(variable assignment; condition; iteration process){for-body}

示例:# /etc/grub2.cfg文件中linux16开头的行统计每一行字段的字符个数,并把大于7个字段的显示出来
[root@localhost ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){if(length($i)>=7){print $i,length($i)}}}' /etc/grub2.cfg
linux16 7
/vmlinuz-3.10.0-693.el7.x86_64 30
root=/dev/mapper/centos-root 28
crashkernel=auto 16
rd.lvm.lv=centos/root 21
LANG=zh_CN.UTF-8 16
linux16 7
/vmlinuz-0-rescue-8e4ba67d04f640d3a12dad38e3d4093b 50
root=/dev/mapper/centos-root 28
crashkernel=auto 16
rd.lvm.lv=centos/root 21


7.5 switch语句(条件判断;字符串比较判断)
语法:switch(expression){case VALUE1 or /GEGEXP/:statement;case VALUE2 or /GEGEXP/:statement;...;default:statement}

7.6 break和continue

  • break [n]:退出N次循环
  • continue:跳出本轮循环,执行下一轮循环

7.7 next:提前结束对本行的处理,而直接进入下一行

示例:  [root@localhost ~]# awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd
        root 0
        daemon 2
        lp 4
        shutdown 6
        mail 8
        games 12
        ftp 14
        systemd-network 192
        libstoragemgmt 998
        rpc 32
        saslauth 996
        rtkit 172
        nfsnobody 65534
        ntp 38
        geoclue 994
        sssd 992
        gdm 42
        sshd 74
        avahi 70
        tcpdump 72
        inspur 1000
        nginx 990

  1. array数组
    关联数组:array[index-expression]
    index-expression:索引表达式
    <1>可使用任意字符串;字符串要使用双引号
    <2>如果某数组元素实现不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”;若要判断数组中是否存在某元素,要使用“index in array” 格式进行
    <3>若要遍历数组中的每个元素,要使用for循环
    注意:var会遍历array的每个元素
示例:
  [root@localhost ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["tue"]}'
Tuesday
[root@localhost ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'
Monday
[root@localhost ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";{for(i in weekdays){print weekdays[i]}}}'
Tuesday
Monday
  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所表示的数组中;

练习1:统计netstat -tan中每个状态各出现多少次

     [root@localhost ~]# netstat -tan | awk  '/^tcp*/{state[$NF]++}END{for(i in state){print i,state[i]}}'
      LISTEN 11
      ESTABLISHED 1

练习2:统计ss -tan中状态各出现多少次

     [root@localhost ~]# ss -tan|awk ' {state[$1]++}END{for(i in       state)print i,state[i]}'
      LISTEN 18
      ESTAB 4
      State 1

练习3:统计/usr/local/apache2/logs/access_log中的IP地址

     [root@localhost ~]# awk '{pingnum[$1]++}END{for(i in pingnum)print i,pingnum[i]}' /usr/local/apache2/logs/access_log 
      192.168.1.104 15

练习4:统计 /etc/fstab 文件中文件系统类型出现的次数

   [root@localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){printf "%-15s %d\n",i,count[i] }}' /etc/fstab
man             1
and/or          1
maintained      1
xfs             3
/dev/mapper/centos-root 1
Accessible      1
\#               7
UUID=55bb7b0d-eb2d-454e-aaaa-fcbf3b0bedcd 1
are             1
defaults        4
blkid(8)        1
/               1
0               8
See             1
1               1
Created         1
on              1
mount(8)        1
anaconda        1
fstab(5),       1
/boot           1
06:20:58        1
findfs(8),      1
/home           1
2018            1
'/dev/disk'     1
by              2
/etc/fstab      1
pages           1
UUID=0a8f2cdd-14bd-4df1-b23a-078f513ad814 1
more            1
info            1
swap            2
Jul             1
Sun             1
filesystems,    1
reference,      1
for             1
under           1
UUID=224da14b-890b-4f1a-8340-5a3ccc016085 1

练习5:统计netstat -tan中IP地址数量

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

你可能感兴趣的:(简述systemd和unit,以及awk命令函数示例)