简述systemd的新特性及unit常见类型分析,能够实现编译安装的如nginx\apache实现通过systemd来管理
systemd是centos7版本新引入的系统级服务管理工具,其主要的新特性有:
- 系统引导时实现服务并行启动
- 按需激活进程(默认情况并没有实际启动进程)
- 支持系统状态快照
- 基于依赖关系来自定义服务的控制逻辑
systemd的核心概念就是unit(单元),将不同的管理资源称之为unit.通过配置文件来进行标识,识别和配置,文件包含了系统服务,监听的套接字文件(socket)及init相关的信息等等.配置文件主要有以下几个:
- /usr/lib/systemd/system
- /run/systemd/system
- /etc/systemd/system
- /lib/systemd/system
unit的常见类型:
Service unit:文件扩展名为.service,用于定义系统服务,如:httpd.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, 用于定义文件系统中的一文件或目录(在某些特殊的情况下使用)
[root@localhost ~]# ls /usr/lib/systemd/system
abrt-ccpp.service oddjobd.service
abrtd.service packagekit-offline-update.service
abrt-oops.service packagekit.service
abrt-pstoreoops.service paths.target
abrt-vmcore.service plymouth-halt.service
abrt-xorg.service plymouth-kexec.service
accounts-daemon.service plymouth-poweroff.service
alsa-restore.service plymouth-quit.service
alsa-state.service plymouth-quit-wait.service
alsa-store.service plymouth-read-write.service
anaconda-direct.service plymouth-reboot.service
anaconda-nm-config.service plymouth-start.service
anaconda-noshell.service plymouth-switch-root.service
anaconda-pre.service polkit.service
anaconda.service postfix.service
anaconda-shell@.service poweroff.target
anaconda-sshd.service poweroff.target.wants
anaconda.target printer.target
anaconda-tmux@.service proc-fs-nfsd.mount
arp-ethers.service proc-sys-fs-binfmt_misc.automount
atd.service proc-sys-fs-binfmt_misc.mount
auditd.service psacct.service
auth-rpcgss-module.service qemu-guest-agent.service
autovt@.service quotaon.service
avahi-daemon.service radvd.service
avahi-daemon.socket rasdaemon.service
basic.target ras-mc-ctl.service
basic.target.wants rc-local.service
blk-availability.service rdisc.service
bluetooth.service rdma-ndd.service
bluetooth.target rdma.service
brandbot.path realmd.service
brandbot.service reboot.target
..... #服务过多,省略了
systemd关键特性工作原理:
- 基于socket的激活机制:
在系统引导时systemd会为所有支持激活该类型的服务分别创建一个socket,并在系统启动后将这个socket传给该服务,实现系统并行启动,并且可以在服务未启动时用systemd去监听这个socket的状态,当有进程访问这个socket时systemd在启动该服务,实现socket与服务程序的分离. - 基于bus的激活机制:
通过监听bus的状态来启动相应服务. - 基于device的激活机制:
在某个硬件设备激活或变为可用时,激活相应服务. - 基于Path的激活机制:
在文件路径变为可用或有文件时,激活相应服务. - 系统快照:
保存各unit的当前状态信息于持久存储设备中,随后服务启动时可用从快照开始继续运行. - 向后兼容sysv init脚本:
兼容性有限,不建议centos7中在使用init命令. - 不兼容:
systemctl的命令格式是固定不变的,不是由systemd启动的服务,systemctl无法与之通信,systemctl不会与任何标准输入流有交流,自行控制其服务的启动.(不能通过交互方式去干涉systemd启动的服务,只能选择用systemd去开启,关闭服务等等.)
管理系统服务:
syscemctl命令:控制systemd系统和其服务管理命令
systemctl [OPTIONS...] COMMAND NAME.service
COMMAND:
start 开启服务 ==> service NAME start (init服务启动方式)
stop 停止服务 ==> service NAME stop
restart 重启服务 ==> service NAME restart
status 查看服务当前状态 ==> service NAME status
enable 开机自启 ==> chkconfig NAME on
disable 开机不自启 ==> chkconfig NAME off
is-enabled 查看服务是否能开机自启 ==> chkconfig --list NAME
reload-or-restart 重载或重启服务
mask 禁止服务设定为开机自启
unmask 取消此禁止
list-dependencies 查看服务的依赖关系
is-active 查看某服务当前激活与否的状态
systemctl list-units -t service --all ==> chkconfig --lsit 查看所有服务
[root@localhost nginx-1.11.10]# systemctl list-units -t service --all
UNIT LOAD ACTIVE SUB DESCRIPTION
abrt-ccpp.service loaded active exited Install ABRT coredump hook
abrt-oops.service loaded active running ABRT kernel log watcher
abrt-vmcore.service loaded inactive dead Harvest vmcores for ABRT
abrt-xorg.service loaded active running ABRT Xorg log watcher
abrtd.service loaded active running ABRT Automated Bug Reporting Tool
accounts-daemon.service loaded active running Accounts Service
alsa-restore.service loaded inactive dead Save/Restore Sound Card State
alsa-state.service loaded active running Manage Sound Card State (restore a
● apparmor.service not-found inactive dead apparmor.service
----------------分割线----------------
[root@localhost nginx-1.11.10]# systemctl status nfs-server.service
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled; vendor preset: disabled)
Active: inactive (dead)
管理target units:
target units用来模拟实现运行级别,target units与init运行级别的对应关系,级别切换,查看等命令:
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(比rescue切换更好)
其它一些常用命令:
关机: systemctl halt, systemctl poweroff
重启: systemctl reboot
挂起: systemctl suspend
快照: systemctl hibernate
快照并挂起: systemctl hybrid-sleep
[root@localhost nginx-1.11.10]# systemctl get-default
graphical.target
service unit file:
文件通常由[Unit],[Service]和[Install]三部分组成:
[root@localhost system]# cat nfs-server.service
[Unit]
Description=NFS server and services
DefaultDependencies=no
Requires= network.target proc-fs-nfsd.mount
Requires= nfs-mountd.service
Wants=rpcbind.socket network-online.target
Wants=rpc-statd.service nfs-idmapd.service
Wants=rpc-statd-notify.service
After= network-online.target local-fs.target
After= proc-fs-nfsd.mount rpcbind.socket nfs-mountd.service
After= nfs-idmapd.service rpc-statd.service
Before= rpc-statd-notify.service
# GSS services dependencies and ordering
Wants=auth-rpcgss-module.service
After=rpc-gssd.service gssproxy.service
Wants=nfs-config.service
After=nfs-config.service
[Service]
EnvironmentFile=-/run/sysconfig/nfs-utils
Type=oneshot
RemainAfterExit=yes
ExecStartPre=-/usr/sbin/exportfs -r
ExecStartPre=-/bin/sh -c '/bin/kill -HUP `cat /run/gssproxy.pid`'
ExecStart=/usr/sbin/rpc.nfsd $RPCNFSDARGS
ExecStop=/usr/sbin/rpc.nfsd 0
ExecStopPost=/usr/sbin/exportfs -au
ExecStopPost=/usr/sbin/exportfs -f
ExecReload=-/usr/sbin/exportfs -r
[Install]
WantedBy=multi-user.target
[Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等
Unit段的常用选项:
Description:有意义性的描述信息
After:定义unit的启动次序,表示当前unit应该晚于哪些unit启动;其功能与Before相反
Requies:指明依赖(强依赖)到的其它units,被依赖的units无法激活时,当前unit即无法激活
Wants:依赖到的其它units;弱依赖,依赖到的uint未激活,当前uint已让可以激活
Conflicts:定义units间的冲突关系
[Service]:与特定类型相关的专用选项;此处为Service类型
Service段的常用选项:
Type:用于定义影响ExecStart及相关参数的功能的unit进程启动类型主要有以下几种:
simple:由ExecStart启动的进程为该程序的主进程
forking:由ExecStart指明的程序启动的进程的子进程会成为主进程,且生成之后主进程会退出
oneshot:一次性的主进程类此simple但启动后续uint之前主进程会退出
dbus:类似simple,后续的uint在当前的uint得到dbus名称之后才能启动
notify:类似simple,后续的uint在通过sdnotify函数发送通知,才能启动
idle:类似simple.
EnvironmentFile:环境配置文件,在ExecStart之前读取并为其提供某些变量
ExecStart:指明启动unit要运行命令或脚本
ExecStartPre: 指明启动unit要运行之前命令或脚本
ExecStartPost:指明启动unit要运行之后命令或脚本
ExecStop:指明停止unit要运行的命令或脚本
Restart:指明重启unit要运行的命令或脚本
[Install]:定义由“systemctl enable”以及"systemctl disable“命令在实现服务启用或禁用时用到的一些选项
Install段的常用选项:
Alias:当前uint的别名
RequiredBy:被哪些units所依赖;
WantedBy:被哪些units所依赖;
注意:对于新创建的unit文件或修改了的unit文件,要使用以下命令通知systemd重载配置文件
systemctl daemon-reload
实现编译安装的如nginx\apache实现通过systemd来管理:
- 安装编译安装依赖的类库和包
[root@localhost ~]# yum install gcc gcc-c++ autoconf automake zlib zlib-devel openssl openssl-devel pcre-devel
Loaded plugins: fastestmirror, langpacks
Repository epel is listed more than once in the configuration
Repository epel-debuginfo is listed more than once in the configuration
Repository epel-source is listed more than once in the configuration
base | 3.6 kB 00:00:00
epel | 4.7 kB 00:00:00
extras | 3.4 kB 00:00:00
updates | 3.4 kB 00:00:00
--> Processing Dependency: kernel-headers >= 2.2.1 for package: glibc-headers-2.17-196.el7_4.2.x86_64
--> Processing Dependency: kernel-headers for package: glibc-headers-2.17-196.el7_4.2.x86_64
---> Package keyutils-libs-devel.x86_64 0:1.5.8-3.el7 will be installed
---> Package libcom_err-devel.x86_64 0:1.42.9-10.el7 will be installed
---> Package libkadm5.x86_64 0:1.15.1-8.el7 will be installed
---> Package libselinux-devel.x86_64 0:2.5-11.el7 will be installed
--> Processing Dependency: libsepol-devel(x86-64) >= 2.5-6 for package: libselinux-devel-2.5-11.el7.x86_64
--> Processing Dependency: pkgconfig(libsepol) for package: libselinux-devel-2.5-11.el7.x86_64
---> Package libverto-devel.x86_64 0:0.2.5-4.el7 will be installed
--> Running transaction check
---> Package glibc-common.x86_64 0:2.17-196.el7 will be updated
---> Package glibc-common.x86_64 0:2.17-196.el7_4.2 will be an update
---> Package kernel-headers.x86_64 0:3.10.0-693.21.1.el7 will be installed
---> Package libsepol-devel.x86_64 0:2.5-6.el7 will be installed
--> Finished Dependency Resolution
# 过程过长省略掉了
Installed:
autoconf.noarch 0:2.69-11.el7 automake.noarch 0:1.13.4-3.el7
gcc.x86_64 0:4.8.5-16.el7_4.2 gcc-c++.x86_64 0:4.8.5-16.el7_4.2
openssl-devel.x86_64 1:1.0.2k-8.el7 pcre-devel.x86_64 0:8.32-17.el7
zlib-devel.x86_64 0:1.2.7-17.el7
Dependency Installed:
cpp.x86_64 0:4.8.5-16.el7_4.2 glibc-devel.x86_64 0:2.17-196.el7_4.2
glibc-headers.x86_64 0:2.17-196.el7_4.2 kernel-headers.x86_64 0:3.10.0-693.21.1.el7
keyutils-libs-devel.x86_64 0:1.5.8-3.el7 krb5-devel.x86_64 0:1.15.1-8.el7
libcom_err-devel.x86_64 0:1.42.9-10.el7 libkadm5.x86_64 0:1.15.1-8.el7
libmpc.x86_64 0:1.0.1-3.el7 libselinux-devel.x86_64 0:2.5-11.el7
libsepol-devel.x86_64 0:2.5-6.el7 libstdc++-devel.x86_64 0:4.8.5-16.el7_4.2
libverto-devel.x86_64 0:0.2.5-4.el7 m4.x86_64 0:1.4.16-10.el7
perl-Test-Harness.noarch 0:3.28-3.el7 perl-Thread-Queue.noarch 0:3.02-2.el7
Dependency Updated:
glibc.x86_64 0:2.17-196.el7_4.2 glibc-common.x86_64 0:2.17-196.el7_4.2
libgcc.x86_64 0:4.8.5-16.el7_4.2 libgomp.x86_64 0:4.8.5-16.el7_4.2
libstdc++.x86_64 0:4.8.5-16.el7_4.2
Complete!
- 下载和解压 Nginx
[root@localhost ~]# wget http://nginx.org/download/nginx-1.11.10.tar.gz
--2018-03-31 20:18:02-- http://nginx.org/download/nginx-1.11.10.tar.gz
Resolving nginx.org (nginx.org)... 206.251.255.63, 95.211.80.227
Connecting to nginx.org (nginx.org)|206.251.255.63|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 967773 (945K) [application/octet-stream]
Saving to: ‘nginx-1.11.10.tar.gz’
100%[===========================================================>] 967,773 78.6KB/s in 13s
2018-03-31 20:18:19 (73.3 KB/s) - ‘nginx-1.11.10.tar.gz’ saved [967773/967773]
[root@localhost ~]# tar -xzvf nginx-1.11.10.tar.gz
nginx-1.11.10/
nginx-1.11.10/auto/
nginx-1.11.10/conf/
nginx-1.11.10/contrib/
nginx-1.11.10/src/
nginx-1.11.10/configure
nginx-1.11.10/LICENSE
nginx-1.11.10/README
nginx-1.11.10/html/
nginx-1.11.10/man/
nginx-1.11.10/CHANGES.ru
.... #包显示过长忽略掉了
----------------------分割线----------------------
[root@localhost ~]# cd nginx-1.11.10/
[root@localhost nginx-1.11.10]#
- 编译安装Nginx
[root@localhost nginx-1.11.10]# ./configure
checking for OS
+ Linux 3.10.0-693.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-16) (GCC)
checking for gcc -pipe switch ... found
checking for -Wl,-E switch ... found
checking for gcc builtin atomic operations ... found
checking for C99 variadic macros ... found
checking for gcc variadic macros ... found
checking for gcc builtin 64 bit byteswap ... found
checking for unistd.h ... found
checking for inttypes.h ... found
checking for limits.h ... found
checking for sys/filio.h ... not found
checking for sys/param.h ... found
checking for sys/mount.h ... found
checking for sys/statvfs.h ... found
checking for crypt.h ... found
checking for Linux specific features
checking for epoll ... found
checking for EPOLLRDHUP ... found
checking for EPOLLEXCLUSIVE ... not found
checking for O_PATH ... found
checking for sendfile() ... found
checking for sendfile64() ... found
checking for sys/prctl.h ... found
checking for prctl(PR_SET_DUMPABLE) ... found
checking for sched_setaffinity() ... found
checking for crypt_r() ... found
checking for sys/vfs.h ... found
checking for nobody group ... found
checking for poll() ... found
checking for /dev/poll ... not found
checking for kqueue ... not found
checking for crypt() ... not found
checking for crypt() in libcrypt ... found
checking for F_READAHEAD ... not found
checking for posix_fadvise() ... found
checking for O_DIRECT ... found
checking for F_NOCACHE ... not found
checking for directio() ... not found
checking for statfs() ... found
checking for statvfs() ... found
checking for dlopen() ... not found
checking for dlopen() in libdl ... found
checking for sched_yield() ... found
checking for SO_SETFIB ... not found
checking for SO_REUSEPORT ... found
checking for SO_ACCEPTFILTER ... not found
checking for SO_BINDANY ... not found
checking for IP_BIND_ADDRESS_NO_PORT ... not found
checking for IP_TRANSPARENT ... found
checking for IP_BINDANY ... not found
checking for IP_RECVDSTADDR ... not found
checking for IP_PKTINFO ... found
checking for IPV6_RECVPKTINFO ... found
checking for TCP_DEFER_ACCEPT ... found
checking for TCP_KEEPIDLE ... found
checking for TCP_FASTOPEN ... found
checking for TCP_INFO ... found
checking for accept4() ... found
checking for eventfd() ... found
checking for int size ... 4 bytes
checking for long size ... 8 bytes
checking for long long size ... 8 bytes
checking for void * size ... 8 bytes
checking for uint32_t ... found
checking for uint64_t ... found
checking for sig_atomic_t ... found
checking for sig_atomic_t size ... 4 bytes
checking for socklen_t ... found
checking for in_addr_t ... found
checking for in_port_t ... found
checking for rlim_t ... found
checking for uintptr_t ... uintptr_t found
checking for system byte ordering ... little endian
checking for size_t size ... 8 bytes
checking for off_t size ... 8 bytes
checking for time_t size ... 8 bytes
checking for AF_INET6 ... found
checking for setproctitle() ... not found
checking for pread() ... found
checking for pwrite() ... found
checking for pwritev() ... found
checking for sys_nerr ... found
checking for localtime_r() ... found
checking for posix_memalign() ... found
checking for memalign() ... found
checking for mmap(MAP_ANON|MAP_SHARED) ... found
checking for mmap("/dev/zero", MAP_SHARED) ... found
checking for System V shared memory ... found
checking for POSIX semaphores ... not found
checking for POSIX semaphores in libpthread ... found
checking for struct msghdr.msg_control ... found
checking for ioctl(FIONBIO) ... found
checking for struct tm.tm_gmtoff ... found
checking for struct dirent.d_namlen ... not found
checking for struct dirent.d_type ... found
checking for sysconf(_SC_NPROCESSORS_ONLN) ... found
checking for openat(), fstatat() ... found
checking for getaddrinfo() ... found
checking for PCRE library ... found
checking for PCRE JIT support ... 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.11.10]# make && make install
make -f objs/Makefile
make[1]: Entering directory `/root/nginx-1.11.10'
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 \
src/core/ngx_log.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_palloc.o \
src/core/ngx_palloc.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_array.o \
src/core/ngx_array.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_list.o \
src/core/ngx_list.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_hash.o \
src/core/ngx_hash.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_buf.o \
src/core/ngx_buf.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_queue.o \
src/core/ngx_queue.c
...... #过程略掉
- 配置 systemd Nginx 服务和设置 Nginx 自启动
创建 systemd 服务文件: /lib/systemd/system/nginx.service内容如下:
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target i
- 重载配置文件并使用systemctl启动nginx服务
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl start nginx.service
[root@localhost ~]# systemctl status nginx.service
● nginx.service - nginx
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2018-03-31 20:35:58 CST; 19s ago
Process: 4781 ExecStart=/usr/local/nginx/sbin/nginx (code=exited, status=0/SUCCESS)
Main PID: 4782 (nginx)
CGroup: /system.slice/nginx.service
├─4782 nginx: master process /usr/local/nginx/sbin/nginx
└─4783 nginx: worker process
Mar 31 20:35:58 localhost.localdomain systemd[1]: Starting nginx...
Mar 31 20:35:58 localhost.localdomain systemd[1]: Started nginx.
提示:本实验只是演示如何用systemctl管理源码包编译的nginx服务,使用默认编译安装,uint配置文件也是相当简单,实际应用还需要做相应的调整
描述awk命令用法及示例(至少3例)
awk是文档的报告生成工具,主要用来格式化文本输出.有awk和gawk两个版本,linux上是gawk版本.awk一次从文本中读取一行,然后对该行按输入分隔符进行切片处理.默认分隔符为空白符.把分出来的每一片到保存到awk内建的变量中,$0代表整行,$1代表第一块切片....$n.最后对其中的某些片段进行过滤,显示等等其他一些操作.
基本用法:
gawk [options] 'program' FILE ...
program: PATTERN{ACTION STATEMENTS}
语句之间用分号分隔
options:
-F:指明输入时用到的字段分隔符
-v var=value: 自定义变量,变量名严格区分字符大小写,并且可以program中直接定义
[root@localhost nginx-1.11.10]# tail -5 /etc/fstab | awk '{print $2,$4}'
/ defaults
/boot defaults
/home defaults
swap defaults
/mnt/media.repo defaults
1. print
print item1, item2, ...
使用要点:
(1) item之间用逗号分隔符.
(2) 输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式.
(3) 如省略item,相当于print $0.
(4) awk中引用变量一般不用" "双引号或者$来引用.
[root@localhost test]# awk '{print 222,$2,$4}' /etc/fstab | tail -5
222 / defaults
222 /boot defaults
222 /home defaults
222 swap defaults
222 /mnt/media.repo defaults
2. 常用的内建变量:
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:一个数组,保存的是命令行所给定的各参数.
[root@localhost nginx-1.11.10]# tail -5 /etc/passwd | awk -v FS=':' -v OFS=':' '{print $2,$4}'
x:70
x:89
x:38
x:72
x:1000
------------------------分割线------------------------
[root@localhost nginx-1.11.10]# awk '{print NF,$NF}' /etc/fstab
0
1 #
2 /etc/fstab
10 2018
1 #
9 '/dev/disk'
12 info
1 #
6 0
6 0
6 0
6 0
6 0
------------------------分割线------------------------
[root@localhost nginx-1.11.10]# awk 'BEGIN{print ARGV[0]}' /etc/fstab
awk #把awk自身当做一个参数
[root@localhost nginx-1.11.10]# awk 'BEGIN{print ARGV[1]}' /etc/fstab
/etc/fstab
3. printf命令
格式化输出:printf FORMAT, item1, item2, ...
(1) FORMAT必须给出.FORMAT为每个item提供一中格式,并对应给出一个字段.
(2) 不会自动换行,需要显式给出换行控制符,\n.
(3) FORMAT中需要分别为后面的每个item指定一个格式化符号.
格式符:
%c: 显示字符的ASCII码
%d, %i: 显示十进制整数
%e, %E: 科学计数法数值显示
%f:显示为浮点数
%g, %G:以科学计数法或浮点形式显示数值
%s:显示字符串
%u:无符号整数
%%: 显示%自身
修饰符:
#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度.例如:
%3.1f :表示显示精度为1且用3个位数显示的浮点数.
-: 左对齐
+:显示数值的符号
[root@localhost test]# awk -F: '{printf "%-10s:%3.2f\n", $1,$3}' /etc/passwd
root :0.00
bin :1.00
daemon :2.00
adm :3.00
lp :4.00
sync :5.00
shutdown :6.00
halt :7.00
mail :8.00
operator :11.00
games :12.00
ftp :14.00
nobody :99.00
systemd-network:192.00
dbus :81.00
polkitd :999.00
abrt :173.00
libstoragemgmt:998.00
rpc :32.00
colord :997.00
saslauth :996.00
rtkit :172.00
chrony :995.00
qemu :107.00
tss :59.00
usbmuxd :113.00
geoclue :994.00
rpcuser :29.00
nfsnobody :65534.00
radvd :75.00
setroubleshoot:993.00
pulse :171.00
gdm :42.00
gnome-initial-setup:992.00
sshd :74.00
avahi :70.00
postfix :89.00
ntp :38.00
tcpdump :72.00
456 :1000.00
named :25.00
apache :48.00
4、操作符
awk支持常用的操作符,如:算术操作符,字符串操作符,赋值操作符,比较操作符,模式匹配符,逻辑操作符等等
算术操作符:
x+y, x-y, x*y, x/y, x^y, x%y
-x
+x: 转换为数值;
字符串操作符:默认没有符号的操作符(做字符串连接)
赋值操作符:
=, +=, -=, *=, /=, %=, ^=
++, -- :自增,自减
比较操作符:
>, >=, <, <=, !=, ==
模式匹配符:
~:是否匹配
!~:是否不匹配
逻辑操作符:
&& 与
|| 或
! 非
[root@localhost test]# awk -F: '{print $3,$4}' /etc/passwd | tail -5
38 38
72 72
1000 1000
25 25
48 48
[root@localhost test]# awk -F: '{print $3*$4}' /etc/passwd | tail -5
1444
5184
1000000
625
2304
----------------分割线----------------
[root@localhost ~]# awk -F: '{$1~"root"?usertype="root":usertype="common user";printf "%10s:%s\n",$1,usertype}' /etc/passwd
root:root
bin:common user
daemon:common user
adm:common user
lp:common user
sync:common user
shutdown:common user
halt:common user
mail:common user
operator:common user
games:common user
ftp:common user
nobody:common user
systemd-network:common user
dbus:common user
polkitd:common user
abrt:common user
libstoragemgmt:common user
rpc:common user
colord:common user
saslauth:common user
rtkit:common user
chrony:common user
qemu:common user
tss:common user
usbmuxd:common user
geoclue:common user
rpcuser:common user
nfsnobody:common user
radvd:common user
setroubleshoot:common user
pulse:common user
gdm:common user
gnome-initial-setup:common user
sshd:common user
avahi:common user
postfix:common user
ntp:common user
tcpdump:common user
456:common user
5. PATTERN匹配模式
awk默认匹配每一行,启动地址定界的功能
(1) empty:空模式,匹配每一行
(2) /regular expression/:仅处理能够被此处的模式匹配到的行
(3) relational expression: 关系表达式;结果有“真”有“假”;结果为“真”才会被处理(真:结果为非0值,非空字符串)
(4) line ranges:行范围,startline,endline:支持/pat1/,/pat2/这种格式,不支持直接给出数字的格式
(5) BEGIN/END模式:对awk起到标记,限定等作用
BEGIN{}: 仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次
[root@localhost ~]# awk -F: '$NF~/bash$/ {print $1,$NF}' /etc/passwd
root /bin/bash
456 /bin/bash
#$NF~/bash$/ :判断最后一个字段是否等于bash,等于则输出
--------------------分割线--------------------
[root@localhost ~]# awk -F: '/^h/,/^g/{print $1,$3}' /etc/passwd
halt 7
mail 8
operator 11
games 12
#匹配以h或以g开头的行
--------------------分割线--------------------
[root@localhost ~]# awk -F: 'BEGIN{print " username uid \n------------------"}/^h/,/^g/{print $1,$3}END{print "==================\n end "}' /etc/passwd
username uid
------------------
halt 7
mail 8
operator 11
games 12
==================
end
6. 常用的action
(1) Expressions : 表达式
(2) Control statements:控制语句.if, while等
(3) Compound statements:组合语句
(4) input statements :输入语句
(5) output statements :输出语句(print,printf)
[root@localhost ~]# awk -F: '{for(i=1;i<NF;i++) {count[$i]++}}END{for(j in count) {print j,count[j]}}' /etc/passwd
rpc 1
8
adm 2
/var/spool/postfix 1
990 1
/var/ftp 1
991 1
/etc/ntp 1
992 1
993 2
Privilege-separated SSH 1
994 1
/bin 1
65534 2
113 2
995 1
radvd 1
996 2
/var/lib/chrony 1
997 2
sync 2
998 2
$i表示该字段的值,如i=1,则$1=rpc,后面的j表示表示如果j在count[j]这个数组中,就打印以索引和对应的索引值,
如:i=1,count[$i]++相当于count[rpc]++,j in count表示j=rpc,并输出count[rpc]的值
......
7. 控制语句
awk可以在处理动作中加入判断,循环等控制语句,来对匹配到的字段进行处理.常见的控制语句如下:
if(condition) {statments} :对awk取得的整行或某个字段做条件判断
if(condition) {statments} else {statements} :同上
if(condition) statement [else statement]
[root@localhost ~]# awk -F: '{if($3<=100) {printf "sys user: %10s\n",$1} else {printf "coomon user: %10s\n",$1}}' /etc/passwd
sys user: root
sys user: bin
sys user: daemon
sys user: adm
sys user: lp
sys user: sync
sys user: shutdown
sys user: halt
sys user: mail
sys user: operator
sys user: games
sys user: ftp
sys user: nobody
coomon user: systemd-network
sys user: dbus
coomon user: polkitd
coomon user: abrt
coomon user: libstoragemgmt
sys user: rpc
coomon user: colord
coomon user: saslauth
coomon user: rtkit
coomon user: chrony
coomon user: qemu
sys user: tss
coomon user: usbmuxd
coomon user: geoclue
sys user: rpcuser
coomon user: nfsnobody
sys user: radvd
coomon user: setroubleshoot
coomon user: pulse
sys user: gdm
coomon user: gnome-initial-setup
sys user: sshd
sys user: avahi
sys user: postfix
sys user: ntp
sys user: tcpdump
coomon user: 456
while(conditon) {statments} :对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用
while(condition) statement
[root@localhost ~]# awk '/^[[:space:]]*save/{i=1;while(i<=NF) {if(length($i)>10) {print $i,length($i)}; i++}}' /etc/grub2.cfg
saved_entry 11
prev_saved_entry 16
saved_entry="${chosen}" 23
saved_entry 11
do {statements} while(condition) :类此while,但至少执行一次循环体.
do statement while(condition)
[root@localhost ~]# awk '/^[[:space:]]*save/{i=1;do {if(length($i)>10) {print $i,length($i)}; i++} while(i<=NF)}' /etc/grub2.cfg
saved_entry 11
prev_saved_entry 16
saved_entry="${chosen}" 23
saved_entry 11
for(expr1;expr2;expr3) {statements} :循环或遍历数组中的元素
for(expr1;expr2;expr3) statement
for(var in array) {for-body} 遍历数组中的元素
[root@localhost ~]# awk '/^[[:space:]]*save/{for(i=1;i<=NF;i++) {if(length($i)>10) {print $i,length($i)}}}' /etc/grub2.cfg
saved_entry 11
prev_saved_entry 16
saved_entry="${chosen}" 23
saved_entry 11
switch :控制开关语句,匹配到的字段符合某项进项处理
switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; ...; default: statement}
在if,while等控制语句中也可以使用中断,退出等.
break 退出循环
continue 结束当前循环并跳转到循环开始处
exit 返回状态码并退出循环
next :awk的特殊语句,提前结束对本行的处理而直接进入下一行
[root@localhost ~]# awk -F: '{if ($NR%2!=0) next; print $1,$2,$3}' /etc/passwd
root x 0
bin x 1
daemon x 2
adm x 3
lp x 4
sync x 5
shutdown x 6
halt x 7
mail x 8
operator x 11
games x 12
ftp x 14
nobody x 99
systemd-network x 192
dbus x 81
polkitd x 999
abrt x 173
libstoragemgmt x 998
rpc x 32
colord x 997
saslauth x 996
rtkit x 172
chrony x 995
qemu x 107
tss x 59
usbmuxd x 113
geoclue x 994
rpcuser x 29
nfsnobody x 65534
radvd x 75
setroubleshoot x 993
pulse x 171
gdm x 42
gnome-initial-setup x 992
sshd x 74
avahi x 70
postfix x 89
ntp x 38
tcpdump x 72
456 x 1000
8. 关联数组:array[index-expression]
awk支持关联数组(自定义的数组)
index-expression:
(1) 可使用任意字符串;字符串要使用双引号
(2) 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”
若要判断数组中是否存在某元素,要使用"index in array"格式进行;
若要遍历数组中的每个元素,要使用for循环;
for(var in array) {for-body}
[root@localhost ~]# awk 'BEGIN{Day["a"]="3.1";Day["b"]="3.2";for(i in Day) {print Day[i]}}'
3.1
3.2
# 注意这里的i在后面输出是不用双引号或者$符号修饰,直接引用i就行
注意:var会遍历array的每个索引;state["a"]++ 表示数组索引的值进行自增
day["mon"]=3,day[mon]++表示3自增.
[root@localhost ~]# awk '{installed[$5]++}END{for(i in installed) {print i,installed[i]}}' /var/log/yum.log
zlib-devel-1.2.7-17.el7.x86_64 1
glibc-headers-2.17-196.el7_4.2.x86_64 1
glances-2.5.1-1.el7.noarch 1
m4-1.4.16-10.el7.x86_64 1
libstdc++-4.8.5-16.el7_4.2.x86_64 1
python2-psutil-2.2.1-3.el7.x86_64 1
epel-release-7-9.noarch 1
pcre-devel-8.32-17.el7.x86_64 1
libverto-devel-0.2.5-4.el7.x86_64 1
glibc-devel-2.17-196.el7_4.2.x86_64 1
autoconf-2.69-11.el7.noarch 1
cpp-4.8.5-16.el7_4.2.x86_64 1
libmpc-1.0.1-3.el7.x86_64 1
1:openssl-devel-1.0.2k-8.el7.x86_64 1
kernel-headers-3.10.0-693.21.1.el7.x86_64 1
keyutils-libs-devel-1.5.8-3.el7.x86_64 1
perl-Test-Harness-3.28-3.el7.noarch 1
libcom_err-devel-1.42.9-10.el7.x86_64 1
libstdc++-devel-4.8.5-16.el7_4.2.x86_64 1
glibc-2.17-196.el7_4.2.x86_64 1
libselinux-devel-2.5-11.el7.x86_64 1
perl-Thread-Queue-3.02-2.el7.noarch 1
gcc-4.8.5-16.el7_4.2.x86_64 1
htop-2.1.0-1.el7.x86_64 1
gcc-c++-4.8.5-16.el7_4.2.x86_64 1
krb5-devel-1.15.1-8.el7.x86_64 1
libkadm5-1.15.1-8.el7.x86_64 1
glibc-common-2.17-196.el7_4.2.x86_64 1
automake-1.13.4-3.el7.noarch 1
libgomp-4.8.5-16.el7_4.2.x86_64 1
libgcc-4.8.5-16.el7_4.2.x86_64 1
dstat-0.7.2-12.el7.noarch 1
libsepol-devel-2.5-6.el7.x86_64 1
tree-1.6.0-10.el7.x86_64 1
描述awk函数示例(至少3例)
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所表示的数组中
[root@localhost ~]# awk '{for(i=1;i<length(NF);i++) print $1}' /etc/passwd
tss:x:59:59:Account
[root@localhost ~]# awk 'BEGIN{rd=int(100*rand());print rd}'
23
[root@localhost ~]# awk 'BEGIN{haha="AVfbsdfc12345ASDFvdf?";gsub(/[0-9]+/,"#_#!!!",haha);print haha}'
AVfbsdfc#_#!!!ASDFvdf?
[root@localhost ~]# awk 'BEGIN{haha="AV fb s d f c 1 23 4 5A SD F v df?";split(haha,Line," ");print length(Line);for(i in Line){print i,Line[i]}}'
14
4 d
5 f
6 c
7 1
8 23
9 4
10 5A
11 SD
12 F
13 v
14 df?
1 AV
2 fb
3 s