4.10 第十三章:Linux系统管理技巧

第十三章:Linux系统管理技巧

13.1监控系统的状态

13.1.1使用w命令查看当前系统的负载

[root@zl_cloud ~]# w
 22:31:49 up 1 min,  2 users,  load average: 0.20, 0.14, 0.06
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     tty1                      22:30    1:33   0.02s  0.02s -bash
root     pts/0    192.168.10.1     22:30    5.00s  0.04s  0.02s w
[root@zl_cloud ~]# 

第1行从左到右显示的信息依次为:时间、系统运行时间、登录用户数、平均负载。
第2行开始的行则是当前登录的用户名及其登录地址等。
第一行load average后面的三个数值为:①表示1分钟内系统的平均负载值。②表示5分钟内系统的平均负载值。③表示15分钟内系统的平均负载值。我们着重看第一个值,它表示单位时间段内使用CPU的活动进程数,值越大说明服务器压力越大。一般情况下,这个值只要不超过服务器的CPU数量就没有关系。

查看服务器有几个CPU的方法:

[root@zl_cloud ~]# cat /proc/cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 142
model name      : Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
stepping        : 10
microcode       : 0xb4
cpu MHz         : 1800.004
cache size      : 6144 KB
physical id     : 0
siblings        : 1
core id         : 0
cpu cores       : 1
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 22
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch arat fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xsaves
bogomips        : 3600.00
clflush size    : 64
cache_alignment : 64
address sizes   : 43 bits physical, 48 bits virtual
power management:

[root@zl_cloud ~]# 

上例中,/proc/cpuinfo这个文件记录了CPU的详细信息。目前市面上的服务器有很多是2颗多核CPU。在Linux看来,它就是2*n个CPU(这里的n为单颗物理机CPU上有几核)。假如n是4,则查看这个文件时会显示8段类似的信息,而最后一段信息的processor:后面会显示7。
查看当前系统又几个CPU:
# grep -C ‘processor’ /proc/cpuinfo
查看有几颗物理CPU时,则需要查看关键字physical id 即可。

13.1.2用vmstat命令监控系统的状态

命令w查看的是系统整体上的负载,通过看那个数值就可以知道当前系统有没有压力。但它无法判断具体是哪里的(CPU、内存、磁盘等)压力,这就用到了vmstat。
vmstat命令打印结果共分为6部分:

[root@zl_cloud ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 1597852    964 166608    0    0   318    18  102  238  1  3 96  0  0
[root@zl_cloud ~]# 

procs显示进程的相关信息。
■r (run):表示运行或等待CPU时间片的进程数。不要误认为等待CPU时间片意味着这个进程没有运行,实际上==某一时刻1个CPU只能有一个进程占用,其他进程只能排着队等着, 此时这些排队等待CPU资源的进程依然是运行状态。==该数值如果长期大于服务器CPU的个数,则说明CPU资源不够用了。
■b (block):表示等待资源的进程数.这个资源指的是I/O、内存等,举个例子.当磁盘读写非常頻繁时,写数据就会非常慢.此时CPU运算很快就结束了,但进程需要把计算的结果写入磁盘,这样进程的任务才算完成,那此时这个进程只能慢慢地等待磁盘了,这样这个进程就是这个b状态。该数值如果长时间大于1.则需要关注一下了。

memory显示内存的相关信息。
■swpd:表示切换到交换分区中的内存数量,单位为KB。
■free:表示当前空闲的内存数量,单位为KB。
■buff:表示(即将写入磁盘的)缓冲大小,单位为KB。
■cache:表示(从磁盘中读取的)缓存大小,単位为KB。

swap显示内存的交换情况。
■si:表示由交换区写入内存的数据量.单位为KB。
■so:表示由内存写入交换区的数据量,单位为KB。

io显示磁盘的使用情况。
■bi:表示从块设备读取数据的量(读磁盘),单位为KB。
■bo:表示从块设备写入数据的量(写磁盘),单位为KB。

system显示采集间隔内发生的中断次数。
■in:表示在某一时间间隔内观测到的毎秒设备的中断次数。
■cs:表示每秒产生的上下文切换次数。

cpu显示CPU的使用状态。
■us:显示用户下所花费CPU的时间百分比。
■sy:显示系统花费CPU的时间百分比。
■id:表示CPU处于空闲状态的时间百分比。
■wa:表示I/O等待所占用CPU的时间百分比。
■st:表示被偷走的CPU所占百分比(一般都为0,不用关注)。

如果磁盘io压力很大,io部分的bi和bo数值会比较高。另外,当si和so两列数值比较高并且不断变化时,说明内存不够了,内存中的数据频繁交换到交换分区中,这往往对系统性能影响极大。
我们使用vmstat查看系统状态时,通常都是使用如下形式:

[root@zl_cloud ~]# vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 1597992    964 166640    0    0   239    14   82  186  1  3 97  0  0
 0  0      0 1597976    964 166640    0    0     0     0   26   32  0  0 100  0  0
 0  0      0 1597976    964 166640    0    0     0     0   26   32  0  1 99  0  0
 0  0      0 1597976    964 166640    0    0     0     0   26   29  0  0 100  0  0
 0  0      0 1597976    964 166640    0    0     0     0   30   38  0  1 99  0  0
[root@zl_cloud ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 1597992    964 166640    0    0   230    13   80  180  1  3 97  0  0
 0  0      0 1597976    964 166640    0    0     0     0   27   32  0  1 99  0  0
 0  0      0 1597976    964 166640    0    0     0     0   26   35  0  1 99  0  0
...
^C
[root@zl_cloud ~]# 

表示每隔1秒输出一次状态,共输出5次,如果想一直输出就不要后面次数5就好了。

13.1.3用top命令显示进程所占的系统资源

top命令用于动态监控进程所占的系统资源,每隔3秒变一次。它的特点是把占用系统资源(CPU、 内存、磁盘I/O等)最高的进程放到最前面。 上例中,top命令打印出了很多信息,包括系统负载(load average)、进程数(Tasks)、CPU使用情况、内存使用情况以及交换分区使用情况。这些内容其实可以通过其他命令来查看,用top重点查看的还是下面的进程使用系统资源的详细状况,其中你需要关 注%CPU、%MEM和COMMAND这几项所代表的意义。RES这一项为进程所占的内存大小,而%MEM这一项为使用内存的百分比。

[root@zl_cloud ~]# top
top - 22:40:27 up 10 min,  2 users,  load average: 0.00, 0.03, 0.05
Tasks: 347 total,   2 running, 345 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1868660 total,  1596920 free,   103528 used,   168212 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  1603572 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND     
   341 root      20   0       0      0      0 S  0.7  0.0   0:03.54 kworker/0:3 
  2401 root      20   0  148408   2276   1456 R  0.3  0.1   0:00.17 top         
     1 root      20   0   44316   6772   4040 S  0.0  0.4   0:02.73 systemd     
     2 root      20   0       0      0      0 S  0.0  0.0   0:00.03 kthreadd    
     3 root      20   0       0      0      0 S  0.0  0.0   0:00.01 ksoftirqd/0 
     7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 migration/0 
     8 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcu_bh      
     9 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/0     
    10 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/1     
    11 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/2     
    12 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/3     
    13 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/4     
    14 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/5     
    15 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/6     
    16 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/7     
    17 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/8     
[root@zl_cloud ~]# 

在top状态下,按Shift+m键可以按照内存使用大小排序。按数字1可以列岀所有核 CPU的使用状态,按q键可以退出top。
另外,还经常用到命令top -bnl.它表示非动态打印系统资源的使用情况,可以用在shell脚本中。示例如下:

[root@zl_cloud ~]# top -bn1 | head
top - 22:47:06 up 17 min,  2 users,  load average: 0.00, 0.01, 0.05
Tasks: 347 total,   2 running, 345 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  1.4 sy,  0.0 ni, 98.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1868660 total,  1596636 free,   103616 used,   168408 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  1603348 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  2406 root      20   0  148404   2124   1388 R  5.9  0.1   0:00.02 top
     1 root      20   0   44316   6776   4044 S  0.0  0.4   0:02.75 systemd
     2 root      20   0       0      0      0 S  0.0  0.0   0:00.03 kthreadd
[root@zl_cloud ~]# 

和top命令唯一的区别就是,它一次性输出所有信息而非动态显示。

13.1.4用sar命令监控系统状态

sar命令很强大,它可以监控系统几乎所有资源的状态,比如平均负载、网卡流量、磁盘状态、内存使用等。与其他系统状态监控工具不同,它可以打印历史信息,可以显示当天从零点开始到当前时刻的系统状态信息。
如果你的系统没有安装这个命令,请使用命令yum install -y sysstat安装。
# yum install -y sysstat

初次使用sar命令会报错,那是因为sar工具还没有生成相应的数据库文件(无需实时监控,因为不用去查询那个库文件)。它的数据库文件在/var/log/sa/目录下。因为这个命令太复杂,所以只介绍以下两个方面。

①查看网卡流量 sar -n DEV

[root@zl_cloud ~]# sar -n DEV
Linux 3.10.0-327.el7.x86_64 (zl_cloud)  2020年04月12日  _x86_64_        (1 CPU)

23时00分01秒     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
23时10分01秒 eno16777736      0.28      0.15      0.02      0.02      0.00      0.00      0.00
23时10分01秒        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
平均时间: eno16777736      0.28      0.15      0.02      0.02      0.00      0.00      0.00
平均时间:        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
[root@zl_cloud ~]# 

这个命令会把当天记录的网卡信息打印出来,每隔10分钟记录一次。 IFACE这一列表示设备名称,rxpck/s这一列表示每秒进入收取的包的数量,txpck/s这一列表示每秒发送出去的包的数量,rxkB/s这一列表示每秒收取的数据量(单位为KB), txkB/s这一列表示每 秒发送的数据量(后面几列不需要关注)。
==如果有一天服务器丢包非常严重,那么你就应该查一下网卡流量是否异常了。==如果txpck/s那一列的数值大于4000,或者rxkB/s那一列的数值大于5000000,很有可能是被攻击了。正常的服务器网卡流 量不会这么高,除非是你自己在复制数据。上例中的命令是查看网卡流量历史的,如果你想实时查看网卡流量,方法如下:

[root@zl_cloud ~]# sar -n DEV 1 5
Linux 3.10.0-327.el7.x86_64 (zl_cloud)  2020年04月12日  _x86_64_        (1 CPU)

23时07分32秒     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
23时07分33秒 eno16777736      2.00      2.00      0.12      0.22      0.00      0.00      0.00
23时07分33秒        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00

23时07分33秒     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
23时07分34秒 eno16777736      0.99      0.99      0.06      0.38      0.00      0.00      0.00
23时07分34秒        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00

23时07分34秒     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
23时07分35秒 eno16777736      0.99      0.99      0.06      0.38      0.00      0.00      0.00
23时07分35秒        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00

23时07分35秒     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
23时07分36秒 eno16777736      0.99      0.99      0.06      0.38      0.00      0.00      0.00
23时07分36秒        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00

23时07分36秒     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
23时07分37秒 eno16777736      1.00      1.00      0.06      0.38      0.00      0.00      0.00
23时07分37秒        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00

平均时间:     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
平均时间: eno16777736      1.19      1.19      0.07      0.35      0.00      0.00      0.00
平均时间:        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
[root@zl_cloud ~]# 

另外==也可以使用-f选择项查看某一天的网卡流量历史,后面跟文件名。==在Red Hat或者CentOS发行版中,sar的库文件一定在/var/log/sa/目录下,如下所示:

[root@zl_cloud ~]# sar -n DEV -f /var/log/sa/sa12 
Linux 3.10.0-327.el7.x86_64 (zl_cloud)  2020年04月12日  _x86_64_        (1 CPU)

23时00分01秒     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
23时10分01秒 eno16777736      0.28      0.15      0.02      0.02      0.00      0.00      0.00
23时10分01秒        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
平均时间: eno16777736      0.28      0.15      0.02      0.02      0.00      0.00      0.00
平均时间:        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
[root@zl_cloud ~]# 

说明:这样就可以查看23号当天的网卡浏量了,不过为什么只有这么一点点呢?这是因为我只在这个时间段开机使用该虚拟机了,正常应该是会记录一整天的。

②查看历史负载 sar -q

[root@zl_cloud ~]# sar -q
Linux 3.10.0-327.el7.x86_64 (zl_cloud)  2020年04月12日  _x86_64_        (1 CPU)

23时00分01秒   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15   blocked
23时10分01秒         1       363      0.00      0.01      0.05         0
平均时间:         1       363      0.00      0.01      0.05         0
[root@zl_cloud ~]# 

这个命令有助于我们査看服务器在过去某个时间的负载状况。其实介绍sar命令,只是为了让你学会查看网卡流量(这是非常有用的)。如果你感兴趣可以man一下,它的用法还有很多。

13.1.5用nload命令查看网卡流量

sar虽然可以查看网卡流量,但是不够直观,还有一个更好用的工具,那就是nload。系统没有默认安装它,安装方法如下:
# yum install -y epel-release; yum install -y nload
关于上面的命令,也许你有疑问,为什么不直接写两个包呢?这是因为要想安装nload,前提是先安装epel-release包,nload包是在epel这个扩展源里面的。以后在工作中,你一定会经常使用epel扩展源安装一些软件包,非常方便。
安装完之后,直接运行nload命令, 然后回车就会出现如下界面。是动态的哦,很直观对不对?相信你会喜欢上这个工具。

[root@zl_cloud ~]# nload 
Device eno16777736 [192.168.10.129] (1/2):
================================================================================
Incoming:




                                                       Curr: 1.73 kBit/s
                                                       Avg: 1.73 kBit/s
                                                       Min: 1.73 kBit/s
                                                       Max: 1.73 kBit/s
                                                       Ttl: 16.81 MByte
Outgoing:




                                                       Curr: 3.53 kBit/s
                                                       Avg: 3.53 kBit/s
                                                       Min: 3.53 kBit/s
                                                       Max: 3.53 kBit/s
                                                       Ttl: 277.32 kByte
 ...
 [root@zl_cloud ~]#

最上面一行为网卡名字以及IP地址,按向右箭头可以查看其他网卡的网络流量。输出结果分为两部分,Incoming为进入网卡的流量,Outgoing为网卡出去的流量,我们关注的当然是Curr那行的数据, 其单位也可以动态自动调整,非常人性化。按q退出该界面。

13.1.6用free命令查看内存使用状况

[root@zl_cloud ~]# free
              total        used        free      shared  buff/cache   available
Mem:        1868660      107108     1412116        8848      349436     1588724
Swap:       2097148           0     2097148
[root@zl_cloud ~]# 

free命令可以查看当前系统的总内存大小以及使用内存的情况。CentOS 7系统的free命令显示结 果比CentOS 6更加简洁了一些,但大体上的内容是一致的。

  • total:内存总大小。
  • used:真正使用的实际内存大小。
  • free:剩余物理内存大小(没有被分配,纯剩余)。
  • shared:共享内存大小,不用关注它。
  • buff/cache:分配给buffer和cache的内存总共有多大。关于buffer和cache大家也许有一些疑惑,因为字面意思上两者很相近。一个很容易区分这两者的方法:buffer和cache都是一部分内存,内存的作用就是缓解CPU和IO(如,磁盘)的速度差距的,你可以这样理解: 数据经过CPU计算,即将要写入磁盘,这时用的内存为buffer; CPU要计算时,需要把数据
    从磁盘中读出来,临时先放到内存中,这部分内存就是cache。
  • available:系统可使用内存有多大,它包含了free。Linux系统为了让应用跑得更快,会预先分配一部分内存(buffer/cache )给某些应用使用,虽然这部分内存并没有真正使用,但也已经分配岀去了。然而,当另外一个服务要使用更多内存时,是可以把这部分预先分配的内存拿来用的。所以还没有被占用的这部分buffer和cache再加上free就是available。
    这个free命令显示的结果中,其实有一个隐藏的公式:total=used+free+buff/cacheo另外, available是由free这部分内存和buff/cache还未被占用的那部分内存组成。used那部分内存和 buff/cache被占用的内存是没有关系的。
    另外free命令还可以加-m和-g选项,甚至也支持 -h选项,这和CentOS 6版本不同。
  • -m:(以MB为单位)打印内存的使用状况;
  • -g:(以GB为单位)打印内存的使用状况。
[root@zl_cloud ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1824         104        1379           8         341        1551
Swap:          2047           0        2047
[root@zl_cloud ~]# 

13.1.7用ps命令查看系统进程

在Linux下如何查看系统进程呢?其实使用前面介绍的top命令就可以,但是查看起来没有ps命令方便,它是专门显示系统进程的命令,如下所示:

[root@zl_cloud ~]# ps aux 
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.3  44316  6796 ?        Ss   22:30   0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2  0.0  0.0      0     0 ?        S    22:30   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        S    22:30   0:00 [ksoftirqd/0]
root          7  0.0  0.0      0     0 ?        S    22:30   0:00 [migration/0]
root          8  0.0  0.0      0     0 ?        S    22:30   0:00 [rcu_bh]
root          9  0.0  0.0      0     0 ?        S    22:30   0:00 [rcuob/0]
root         10  0.0  0.0      0     0 ?        S    22:30   0:00 [rcuob/1]
root         11  0.0  0.0      0     0 ?        S    22:30   0:00 [rcuob/2]
root         12  0.0  0.0      0     0 ?        S    22:30   0:00 [rcuob/3]
...
[root@zl_cloud ~]# 

下面介绍几个系统进程的参数:

  • PID:表示进程的ID,这个ID很有用。在Linux中,内核管理进程就得靠pid来识别和管理某一个进程。比如我想终止某一个进程,则用命令“kill进程的pid”。有时这样并不能终止进 程,需要加-9选项,即“kill -9进程的pid”,但这样有点暴力,严重的时候会丢数据,所 以尽量还是别用。
  • STAT:进程的状态。进程状态分为以下几种(不要求记住,但要了解)。
    ■D:不能中断的进程(通常为IO )。
    ■R (run):正在运行中的进程,其中包括了等待CPU时间片的进程。
    ■S (sleep):已经中断的进程。通常情况下,系统的大部分进程都是这个状态。
    ■T:已经停止或者暂停的进程。如果我们正在运行一个命令,比如说sleep 10,我们按一下 Ctrl+Z暂停进程时,用ps命令查看就会显示T这个状态。
    ■W:(内核2.6xx以后不可用),没有足够的内存页分配,
    ■X:已经死掉的进程(这个好像从来不会出现)o
    ■Z:僵尸进程,即杀不掉、打不死的垃圾进程,占用系统一点资源,不过没有关系。如果占用太多(一般不会出现),就需要重视了。
    ■<:高优先级进程。
    ■N:低优先级进程。
    ■L:在内存中被锁了内存分页。
    ■s:主进程,后面讲到nginx或<php-fpm服务的时候,你就能更好地理解它了。
    ■l:多线程进程。
    ■ +:在前台运行的进程,比如在当前终端执行ps aux就是前台进程。
    ps命令是在工作中用得非常多的一个命令,所以请记住它。经常会将ps连同管道符一起使用,用来查看某个进程或者它的数量。示例命令如下:
[root@zl_cloud ~]# ps aux |grep -c sshd
3
[root@zl_cloud ~]# ps aux |grep sshd
root       1186  0.0  0.2 108104  4096 ?        Ss   22:30   0:00 /usr/sbin/sshd -D
root       2372  0.0  0.2 149912  5292 ?        Ss   22:30   0:00 sshd: root@pts/0
root       2579  0.0  0.0 112728   964 pts/0    R+   23:49   0:00 grep --color=auto sshd
[root@zl_cloud ~]# 

上例中的3不准确,需要减掉1。因为使用grep命令时,grep命令本身也算一个进程。

13.1.8用netstat命令查看网络状况

先安装软件包:
# yum install -y net-tools

[root@zl_cloud ~]# netstat -lnp |head
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1186/sshd           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1574/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1186/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1574/master         
raw6       0      0 :::58                   :::*                    7           953/NetworkManager  
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
unix  2      [ ACC ]     STREAM     LISTENING     16647    1/systemd            /var/run/dbus/system_bus_socket
[root@zl_cloud ~]# 

显示的结果中,上面那一部分是tcp/ip,下面一部分是监听的socket ( unix开头的行)。netstat命令用来打印网络连接状况、系统所开放端口、路由表等信息。最常用的两种用法是netstat -lnp (打印当前系统启动哪些端口)和netstat -an(打印网络连接状况),它们非常有用,请一定要记住。

[root@zl_cloud ~]# netstat -an |head
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp        0     52 192.168.10.129:22       192.168.10.1:52272      ESTABLISHED
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:25                  :::*                    LISTEN     
raw6       0      0 :::58                   :::*                    7          
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path
[root@zl_cloud ~]# 

最右侧为网络连接的状态,如果你对TCP三次握手比较熟悉,那应该对最后这一列的字符串不陌生。如果你管理是一台提供Web服务(80端口)的服务器,那么就可以使用命令netstat -an |grep 80 来查看当前连接Web服务的有哪些IP 了。

13.2抓包工具

有时也许想看一下某个网卡上都有哪些数据包,尤其是当你初步判定服务器上有流量攻击时,使 用抓包工具来抓取数据包就可以知道有哪些ip在攻击了。

13.2.1tcpdump 工具

初次使用应安装下列软件包:
# yum install -y tcpdump

[root@zl_cloud ~]# tcpdump -nn -i eno16777736 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno16777736, link-type EN10MB (Ethernet), capture size 262144 bytes
00:08:02.944530 IP 192.168.10.129.22 > 192.168.10.1.52272: Flags [P.], seq 1790786219:1790786415, ack 3320638244, win 272, length 196
00:08:02.944861 IP 192.168.10.1.52272 > 192.168.10.129.22: Flags [.], ack 196, win 4100, length 0
00:08:02.945201 IP 192.168.10.129.22 > 192.168.10.1.52272: Flags [P.], seq 196:472, ack 1, win 272, length 276
00:08:02.945535 IP 192.168.10.129.22 > 192.168.10.1.52272: Flags [P.], seq 472:636, ack 1, win 272, length 164
00:08:02.945731 IP 192.168.10.1.52272 > 192.168.10.129.22: Flags [.], ack 636, win 4106, length 0
00:08:02.945835 IP 192.168.10.129.22 > 192.168.10.1.52272: Flags [P.], seq 636:896, ack 1, win 272, length 260
00:08:02.946043 IP 192.168.10.129.22 > 192.168.10.1.52272: Flags [P.], seq 896:1060, ack 1, win 272, length 164
...

回车后会出现密密麻麻的一堆字符串,在按Ctrl+C之前,这些字符串一直在刷屏,刷屏越快说明网卡上的数据包越多。上例中,我们只需要关注第3列和第4列,它们显示的信息为哪一个IP+端口号在连接哪一个IP+端口号。后面的信息是该数据包的相关信息,如果不懂也没有关系。

  • -i:选项后面跟设备名称,如果想抓取其他网卡的数据包,后面则要跟其他网卡的名字。
  • -nn:其作用是让第3列和第4列显示成“IP+端口号”的形式,如果不加-nn选项则显示“主机名+服务名称”。
  • -c:指定抓包数量,抓够了自动退出,不用人为取消。
    #tcpdump -nn -i ens33 -c 100 //抓够100条自动退出
    #tcpdump -nn -i ens33 port 22// 这样指定只抓22端口的包
    #tcpdump -nn -i ens33 tcp and not port 22 // 指定抓tcp的包,但是不要22端口的
    #tcpdump -nn -i ens33 port 22 and port 53 // 只抓22和53端口的包

13.2.2wireshark 工具

也许你在WindowsT使用过wireshark这个抓包工具,它的功能非常强大。在Linux平台我们同样也可以使用它,只不过是以命令行的形式。wireshark的具体选项不再详细介绍,在日常工作中, tcpdump其实就已经够我们使用了。
要执行的命令是tshark,虚拟机默认是没有这个命令的:
# yum install -y wireshark

13.3Linux 网络相关

13.3.1用ifconfig命令查看网卡IP

前面曾用过ip addr这个命令来查看系统的IP地址。其实在CentOS 7之前,我们使用最多的命 令是if conf ig,它类似于Windows的ipconfig命令,后面不加任何选项和参数时,只打印当前网卡IP 的相关信息(如子网掩码、网关等)。
如果没有ifconfig命令,则安装:
# yum install -y net-tools
在Windows下设置IP非常简单,然而在命令窗口下如何设置呢?
# vi /etc/sysconfig/network-scripts/ifcfg-xxx
如果Linux上有多个网卡,而你只想重启某一个网卡的话,可以使用:
# ifdown ens33;ifup ens33

ifdown即停用网卡,if叩即启动网卡。需要大家注意的是,如果我们远程登录服务器,当使用命 令ifdown ens33时,很有可能后面的命令ifup ens33不会运行。这样会导致我们断网而无法连接服务 器,所以请尽量使用命令# systemctl restart network来重启网卡。

13.3.2给一个网卡设定多个IP

在Linux系统中,网卡是可以设定多重IP的:

[root@zl_cloud ~]# cd /etc/sysconfig/network-scripts/
[root@zl_cloud network-scripts]# cp ifcfg-eno16777736 ifcfg-eno16777736\:1

之所以加反斜杠(\),是因为要把:转义,不然在Linux命令行下面无法识别。然后编辑 ifcfg-ens33:l这个配置文件。一定要注意DEVICE要写成ens33:l,如下所示:

[root@zl_cloud network-scripts]# cat ifcfg-eno16777736\:1
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=eno16777736:1
UUID=fcceef03-6a7c-4881-810c-24531b699adf
DEVICE=eno16777736:1
ONBOOT=yes
IPADDR=192.168.10.200
NETMASK=255.255.255.0
GATEWAY=192.168.10.2
DNS1=8.8.8.8
[root@zl_cloud network-scripts]# 

其实就是改一下NAME、DEVICE、IPADDR,设置完毕重启网卡,如下所示:

[root@zl_cloud ~]# ifdown eno16777736;ifup eno16777736
Device 'eno16777736' successfully disconnected.
成功激活的连接(D-Bus 激活路径:/org/freedesktop/NetworkManager/ActiveConnection/1)
[root@zl_cloud ~]# ifconfig
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.129  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::20c:29ff:fe68:3343  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:68:33:43  txqueuelen 1000  (Ethernet)
        RX packets 31630  bytes 35145034 (33.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10845  bytes 1724393 (1.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eno16777736:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.200  netmask 255.255.255.0  broadcast 192.168.10.255
        ether 00:0c:29:68:33:43  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@zl_cloud ~]#

从上面可以看到多了一个eno16777736:1

13.3.3查看网卡连接状态

[root@zl_cloud ~]# mii-tool eno16777736
eno16777736: negotiated 1000baseT-FD flow-control, link ok

这里显示link ok,就说明网卡为连接状态。如果显示no link,说明网卡坏了或者没有连接网线 还有一个命令也可以查看网卡的状态,如下:

[root@zl_cloud ~]# ethtool eno16777736
Settings for eno16777736:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Full 
        Supported pause frame use: No
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Full 
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: off (auto)
        Supports Wake-on: d
        Wake-on: d
        Current message level: 0x00000007 (7)
                               drv probe link
        Link detected: yes
[root@zl_cloud ~]# 

如果网卡没有连接,最后面一行Link detected显示为no。

13.3.4更改主机名

# hostnamectl set-hostname zl_cloud

重启就可以了。

13.3.5设置 DNS

DNS是用来解析域名的。平时我们访问网站都是直接输入一个网址,而DNS把这个网址解析到一 个IP。
在Linux下设置DNS非常简单,只要把DNS地址写到配置文件/etc/resolv.conf中即可。如下所示:

[root@zl_cloud ~]# cat /etc/resolv.conf 
# Generated by NetworkManager
nameserver 8.8.8.8A
[root@zl_cloud ~]# 

第一行以#开头的行没有实际意义,仅仅是一个注释,它的意思是,这个配置文件中的DNS IP地址是由NetworkManager服务生成的。
NetworkManager是一个集成的Linux网络管理器,不过从来没有用过它,所以不做更多介绍。那么为什么这个DNS由它生成呢?你是否还有印象,我们在定义网卡配置文件的时候,就有一行DNS1=8.8.8.8,其实就是因为这行配置,该配置文件里才有了 nameserver的IP地址。resolv.con有它固有的格式,一定要写成nameserver IP的格式。建议你写两个或多个namserver,系统默认会用第一个namserver去解析域名,当第一个解析不成功时会使用第 二个。
说到这,你是否有疑惑:既然两个地方都可以定义DNS的IP地址,那么到底在哪里定义呢:如果只是临时修改DNS IP地址,就直接修改/etc/resolv.conf;如果是永久生效的话,还是要修改网卡的配置文件。
在Linux下还有一个特殊文件/etc/hosts也能解析域名,不过需要我们在里面手动添加IP和域名这些 内容。它的作用是临时解析某个域名,非常有用。该文件的内容如下:

[root@zl_cloud ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

请用Vim编辑该文件,增加一行192.168.188.1 www.baidu.com ,保存文件后再ping—下 www.baidu.com就会连接到 192.168.188.1 了。如下所示:

[root@zl_cloud ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.188.1 www.baidu.com

[root@zl_cloud ~]# ping -c3 www.baidu.com
PING www.baidu.com (192.168.188.1) 56(84) bytes of data.
^C
--- www.baidu.com ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1000ms

[root@zl_cloud ~]#

/etc/hosts的格式很简单,每一行为一条记录,分成两部分,第一部分是IP,第二部分是域名。关 于hosts文件,有以下几点需要你注意:

  • 一个IP后面可以跟多个域名,可以是几十个甚至上百个;
  • 每一行只能有一个IP,也就是说一个域名不能对应多个IP;
  • 如果有多行中出现相同的域名(对应的IP不一样),会按最前面出现的记录来解析。

13.4Linux 的防火墙

13.4.1SELinux

SELinux是Linux系统特有的安全机制。因为这种机制的限制太多,配置也特别烦琐,所以几乎没 有人真正应用它。安装完系统,我们一般都要把SELinux关闭,以免引起不必要的麻烦。临时关闭 SELinux的方法为:
#setenforce 0
但这仅仅是临时的,要想永久关闭需要更改配置文件/etc/selinux/config,需要把SELINUX= enforcing 改成SELINUX=disabled,更改后的内容如下所示:

#cat /etc/selinux/config
#This file controls the state of SELinux on the system.
#SELINUX= can take one of these three values:
#enforcing - SELinux security policy is enforced.
#permissive - SELinux prints warnings instead of enforcing.
#disabled - No SELinux policy is loaded.
SELINUX=disabled
#SELINUXTYPE= can take one of three two values:
#targeted - Targeted processes are protected,
#minimum - Modification of targeted policy. Only selected processes are protected.
#mis - Multi Level Security protection.
SELINUXTYPE=targeted

更改完该配置文件后,重启系统方可生效。可以使用getenforce命令获得当前SELinux的状态,如下所示:

# getenforce
Disabled

我的SELinux早就关闭了,默认会输出enforcing□当使用setenforce 0这个命令后,再执行 getenforce 命令会输出 permissive。

13.4.2netfilter

在之前的CentOS版本(比如5和6 )的防火墙为netfilter, CentOS7的防火墙为firewalld。很多朋友把Linux的防火墙叫作iptables,其实这样叫并不太恰当,iptables仅仅是一个工具。
当然,即使是firewalld,同样也支持之前版本的命令用法,也就是说它是向下兼容的。首先要大概过一下之前版本iptables的常用用法,毕竟目前很多企业使用的CentOS系统依然是6。然后,再介绍一下firewalld的一些用法。下面先写如何把firewalld关闭,然后开启之前版本的iptables。示例命令如下:

#systemctl stop firewalld // 关闭firewalld服务
#systemctl disable firewalld //禁止firewalld服务开机启动,后面将会详细讲解 Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallDl.service. Removed symlink /etc/systemd/system/basic.target.wants/firewalld.service.
#yum install -y iptables-services // 安装iptables-services,这样就可以使用之前版本的iptablesT
#systemctl enable iptables // 让它开机启动
Created symlink from /etc/systemd/system/basic.target.wants/iptables.service to /usr/lib/systemd/system/iptables.service.
#systemctl start iptables // 启动 iptables服务

到此,咱们就可以使用之前版本的iptables了。CentOS上默认设有iptables规则,这个规则虽然很安全,但对于我们来说没有用,反而会造成某些影响,所以建议你先清除规则,然后把清除后的规则保存一下。示例命令如下:

[root@zl_cloud ~]# iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  446 30174 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
    2   128 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
    0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 293 packets, 27711 bytes)
 pkts bytes target     prot opt in     out     source               destination         
[root@zl_cloud ~]#  iptables -F ;service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [  确定  ]
[root@zl_cloud ~]# 

上例中,-nvL选项表示查看规则,-F选项表示清除当前规则,但清除只是临时的,重启系统或者重启iptalbes服务后还会加载已经保存的规则,所以需要使用service iptables save保存一下规则。 通过上面的命令输出,我们也可以看到,防火墙规则保存在/etc/sysconfig/iptables中,你可以査看一下这个文件。

①netfilter的5个表

  • filter表主要用于过滤包,是系统预设的表,这个表也是用得最多的表。该表内建3个链: INPUT、OUTPUT以及FORWARD。INPUT链作用于进入本机的包,OUTPUT链作用于本机送出的包,FORWARD链作用于那些跟本机无关的包。
  • nat表主要用于网络地址转换,它也有3个链。PREROUTINC链的作用是在包刚刚到达防火墙时改变它的目的地址(如果需要的话),OUTPUT链的作用是改变本地产生的包的目的地址,POSTROUTING链的作用是在包即将离开防火墙时改变其源地址。该表仅偶尔会用到。
  • mangle表主要用于给数据包做标记,然后根据标记去操作相应的包。这个表几乎不怎么用,除非你想成为一个高级网络工程师,否则就不需要太关注。
  • raw表可以实现不追踪某些数据包,默认系统的数据包都会被追踪,但追踪势必消耗一定的资源, 所以可以用raw表来指定某些端口的包不被追踪。这个表,我从来没用过。
  • security表在CentOS6中是没有的,它用于强制访问控制(MAC)的网络规则。可以说这个表都没有深入研究过,更别说使用了。所以,你暂时不用理会它。

②netfilter的5个链

5个链分别为PREROUTING. INPUT、FORWARD、OUTPUT, POSTROUTING。

  • PREROUTINC:数据包进入路由表之前。
  • INPUT:通过路由表后目的地为本机。
  • FORWARDING:通过路由表后,目的地不为本机。
  • OUTPUT:由本机产生,向外转发。
  • POSTROUTIONG:发送到网卡接口之前。
    具体的数据包流向,可以参考下图。
    在这里插入图片描述

表和链对应的关系如下图:

在这里插入图片描述

③iptables基本语法

iptables是一个非常复杂和功能丰富的工.具,所以它的语法也是很有特点的。下面就给大家介绍几种常用的语法。

(1)査看规则以及清除规则,其用法如下:

[root@zl_cloud ~]# iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination   
...      
[root@zl_cloud ~]# 

-t选项后面跟表名,-nvL表示査看该表的规则,其中-n表示不针对IP反解析主机名,-L表示列出, -V表示列出的信息更加详细。如果不加-t选项,则打印filter表的相关信息,如下所示:

[root@zl_cloud ~]# iptables -nvL
Chain INPUT (policy ACCEPT 109 packets, 7530 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 54 packets, 5768 bytes)
 pkts bytes target     prot opt in     out     source               destination         
[root@zl_cloud ~]# 

上例和-t filter打印的信息是一样的。关于清除规则的命令中,用得最多就是下面两个:
#iptables -F
#iptables -Z
这里-F表示把所有规则全部删除,如果不加-t指定表,默认只清除filter表的规则。-Z表示把包以及流量计数器置零(这个很有用)

(2)增加/删除一条规则,其用法如下:

#iptables -A INPUT -s 192.168.188.1 -p tcp --sport 1234 -d 192.168.188.128 --dport 80 -j DROP
这里没有加-t选项,所以针对的是filter表。这条规则中各个选项的作用如下。

  • -A/-D:表示增加/删除一条规则。
  • -I:表示插入一条规则,其实效果跟-A一样。
  • -p:表示指定协议,可以是tcp、udp或者icmp。
  • -P:预设策略。(例如 # iptables -P INPUT DROP。-P后面跟链名,策略内容为DROP、ACCEPT,默认为ACCEPT。在远程时不要随便执行,一旦回车就会断开连接。策略一旦设定后,只有使用# iptables -P INPUT ACCEPT才能恢复成原始状态。)
  • --dport:跟-p—起使用,表示指定目标端口。
  • --sport:跟-p—起使用,表不指定源端口。
  • -s:表示指定源IP (可以是一个IP段)。
  • -d:表示指定目的IP (可以是一个IP段)。
  • -j:后面跟动作,其中ACCEPT表示允许包,DROP表示丢掉包,REJECT表示拒绝包。
  • -i:表示指定网卡(不常用,但偶尔能用到)。

④nat表的使用

路由器的功能其实就是由Linux的iptables实现 的,而iptables又是通过nat表作用而实现的。举个例子说明iptables时如何实现这个功能的:
假设你的机器上有两块网卡eth0 和eth1,其中eth0的IP为10.0.2.68, eth1的IP为192.168.1.1。eth0连接了因特网,但ethl没有连接。现在有另一台机器(192.168.1.2 )和ethl是互通的,那么如何设置才能让连接ethl的这台机器连接因特网, 和10.0.2.68互通呢?方法很简单,如下所示:

#echo "1" > /proc/sys/net/ipv4/ip_forward
#iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ethO -j MASQUERADE

这里,第一个命令涉及内核参数相关的配置文件,它的目的是打开路由转发功能,否则无法实现我们的应用。第二个命令则是iptables对nat表做了一个IP转发的操作。-O选项后面跟设备名,表示出口的网卡;MASQUERADE表示伪装。关于nat表,只要学会这个路由转发功能即可。

⑤保存和备份iptables规则

前面提到过,咱们设定的防火墙规则只保存在内存中,并没有保存到某一个文件中。也就是 说,当系统重启后以前设定的规则就没有了,所以设定好规则后要先保存一下。命令如下:

#service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ 确定 ]

它会提示你防火墙规则保存在/etc/sysconfig/iptables文件内,这个文件就是iptables的配置文件。所 以日后如果你遇到备份防火墙规则的任务,只要复制一份这个文件的副本即可。
有时我们需要清除防火墙的所有规则,使用命令iptables -F固然可以,但最好的办法还是停止防火墙服务,如下所示:

#service iptables stop
iptables:浦除防火墻规则:	[确定]
iptables:将链设置为政策ACCEPT:	nat filter	j确定j
iptables:正在却载模块:	j确定j

这样防火墙就失效了,但是一旦重新设定规则(哪怕只有一条),防火墙服务会自动开启。使用iptables -save保存规则后,若想恢复这些规则,则:
# iptables -restore < myipt.rule

13.4.3firewalld

先打开:

[root@zl_cloud ~]# systemctl disable iptables
Removed symlink /etc/systemd/system/basic.target.wants/iptables.service.
[root@zl_cloud ~]# systemctl stop iptables
[root@zl_cloud ~]# systemctl enable firewalld
Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.
Created symlink from /etc/systemd/system/basic.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.
[root@zl_cloud ~]# systemctl start firewalld
[root@zl_cloud ~]#   

firewalld有两个基础概念,分别是zone和service,每一个zone里面有不同的iptables规则,默认一共 有9个zone,而CentOS 7默认的zone为public。获取系统所有的zone,命令如下所示:

	[root@zl_cloud ~]# firewall-cmd --get-zones
	block dmz drop external home internal public trusted work
	[root@zl_cloud ~]# 
	如下命令可以查看系统默认的zone:
	[root@zl_cloud ~]# firewall-cmd --get-default-zone
	public
	[root@zl_cloud ~]# 

下面简单介绍一下上面提到的9个zone。

  • drop (丢弃):任何接收的网络数据包都被丢弃,没有任何回复。仅能有发送出去的网络连接。
  • block (限制):任何接M攵的网络连接都被IPv4的icmp-host-prohibited信息和IPv6的 icmp6-adm-prohibited 信息所拒绝 o
  • public (公共):在公共区域内使用,不能相信网络内的其他计算机不会对你的计算机造成危害,只能接收经过选取的连接。
  • external (外部):特别是为路由器启用了伪装功能的外部网。你不能信任来自网络的其他计算,不能相信它们不会对你的计算机造成危害,只能接收经过选择的连接。
  • dmz (非军事区):用于你的非军事区内的计算机,此区域内可公开访问,可以有限地进入你 的内部网络,仅仅接收经过选择的连接。
  • work(工作):用于工作区。你可以基本相信网络内的其他计算机不会危害你的计算机。仅仅 接收经过选择的连接。
  • home(家庭):用于家庭网络。你可以基本信任网络内的其他计算机不会危害你的计算机。仅 仅接收经过选择的连接。
  • internal(内部):用于内部网络。你可以基本上信任网络内的其他计算机不会威胁你的计算 机。仅仅接受经过选择的连接。
  • trusted (信任):可接受所有的网络连接。
    对于以上9个zone简单了解即可,相信你在日常工作中使用它们的机会不会太多。下面介绍几个关于zone的命令:
    #firewall-cmd --set-default-zone=work //设定欢认的zone为work success
    #firewall-cmd --get-zone-of-interface=ens33 //查看指定网卡所在的zoneWork
    #firewall-cmd --zone=public --add-interface=lo //给指定网卡设置zone
    success
    #firewall-cmd --zone=dmz - -change- interface=lo//针对网卡更改 zone
    success
    #firewall-cmd --zone=dmz - -remove- interf ace=lo//针对网卡删除 zone
    success
    #firewall-cmd --get-active-zones〃查看系统所有网卡所在的zoneWork
    interfaces: ens33
    在CentOS7中使用firewalld,开发者可能是想简化用户的使用过程,在提供的9种zone中, 总有一个是适合我们的使用场景的。那到底zone是什么?每一种zone之间到底有什么区别呢?下面再给大家介绍一个概念一service。其实,之所以有9种zone,是因为每一个zone里面都使用了不同的service,而service就是针对一个服务(端口)做的iptables规则。
	[root@zl_cloud ~]# firewall-cmd --get-service  //列出当前系统所有的service
	RH-Satellite-6 amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns 	freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imaps 	ipp ipp-client ipsec iscsi-target kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns 	mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3s postgresql 	proxy-dhcp radius rpc-bind rsyncd samba samba-client smtp ssh telnet tftp tftp-client 	transmission-client vdsm vnc-server wbem-https
	[root@zl_cloud ~]# 

这些service都是由一个个配置文件定义的,配置文件的模板在/usr/lib/firewalld/services/目录下,真 正生效的配置在/etc/firewalld/services 目录下面(默认为空):

	[root@zl_cloud ~]# ls /usr/lib/firewalld/services/
	amanda-client.xml        iscsi-target.xml  pop3s.xml
	bacula-client.xml        kerberos.xml      postgresql.xml
	bacula.xml               kpasswd.xml       proxy-dhcp.xml
	dhcpv6-client.xml        ldaps.xml         radius.xml
	dhcpv6.xml               ldap.xml          RH-Satellite-6.xml
	dhcp.xml                 libvirt-tls.xml   rpc-bind.xml
	dns.xml                  libvirt.xml       rsyncd.xml
	freeipa-ldaps.xml        mdns.xml          samba-client.xml
	freeipa-ldap.xml         mountd.xml        samba.xml
	freeipa-replication.xml  ms-wbt.xml        smtp.xml
	ftp.xml                  mysql.xml         ssh.xml
	high-availability.xml    nfs.xml           telnet.xml
	https.xml                ntp.xml           tftp-client.xml
	http.xml                 openvpn.xml       tftp.xml
	imaps.xml                pmcd.xml          transmission-client.xml
	ipp-client.xml           pmproxy.xml       vdsm.xml
	ipp.xml                  pmwebapis.xml     vnc-server.xml
	ipsec.xml                pmwebapi.xml      wbem-https.xml
	[root@zl_cloud ~]# 

每个zone里面都有不同的service,那如何查看一个zone下面有哪些service呢?

	[root@zl_cloud ~]# firewall-cmd --list-services
	dhcpv6-client ssh
	[root@zl_cloud ~]# firewall-cmd --zone=public --list-services
	dhcpv6-client ssh
	[root@zl_cloud ~]# 

一个zone下面有某个service,意味着这个service是被信任的。比如,当前zone下面有ssh,那么ssh 服务(也就是22)端口是放行的。我们可以给一个zone添加一个service,命令如下:

[root@zl_cloud ~]# firewall-cmd --zone=public --add-service=http
success
[root@zl_cloud ~]# firewall-cmd --zone=public --list-service
dhcpv6-client http ssh
[root@zl_cloud ~]# 

对于每个zone来说,都有自己的配置文件,你可以查看目录/usr/lib/firewalld/zones/下面对应的文 件,这些就是zone的配置文件:

[root@zl_cloud ~]# ls /usr/lib/firewalld/zones/
block.xml  drop.xml      home.xml      public.xml   work.xml
dmz.xml    external.xml  internal.xml  trusted.xml
[root@zl_cloud ~]# 

可在一个zone里面增加一个service,但这种方法仅仅在内存中生效,并没有修改配置文件,如果想修改配置文件,需要加一个选项:

[root@zl_cloud ~]# firewall-cmd --zone=public --add-service=http --permanent 
success
[root@zl_cloud ~]# 

一旦更改了某个zone的配置文件,则会在/etc/firewalld/zones/目录下面生成对应zone的配置文件 (.xml后缀的文件),其实这个目录下面的配置文件才是真正的配置文件。在上面介绍的目录,可以说是所有zone的模板配置文件。
下面举一个实际的例子,帮助你明白zone和service两个概念。需求:假如服务器上配置了一 个FTP服务,但端口并非默认的21,而是1121,并且需要在work zone下面放行FTP。具体的做法如下:

[root@zl_cloud ~]# cp /usr/lib/firewalld/services/ftp.xml /etc/firewalld/services/ 
[root@zl_cloud ~]# vi /etc/firewalld/services/ftp.xml   //把21改成1121
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>FTP</short>
  <description>FTP is a protocol used for remote file transfer. If you plan to make your FTP server publicly available, enable this option. You need the vsftpd package installed for this option to be useful.</description>
  <port protocol="tcp" port="1121"/>
  <module name="nf_conntrack_ftp"/>
</service>
[root@zl_cloud ~]# cp /usr/lib/firewalld/zones/work.xml /etc/firewalld/zones/
[root@zl_cloud ~]# vi /etc/firewalld/zones/work.xml  //增加一行FTP的相关配置
<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Work</short>
  <description>For use in work areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="ssh"/>
  <service name="ipp-client"/>
  <service name="dhcpv6-client"/>
</zone>
# firewall-cmd --reload
[root@zl_cloud ~]# 

再来验证一下work zone里面的service是否有FTP:

[root@zl_cloud ~]# firewall-cmd --zone=work --list-services
dhcpv6-client ipp-client ssh
[root@zl_cloud ~]# 

13.5Linux系统的任务计划

其实大部分系统管理工作都是通过定期自动执行某个脚本来完成的,那么如何定期执行某个脚本 呢?这就要借助Linux的cron功能了。这部分内容很重要,请大家牢记!

13.5.1命令crontab

Linux任务计划功能的操作都是通过crontab命令来完成的,其常用的选项有以下几个。

  • -u:表示指定某个用户,不加-u选项则为当前用户。
  • -e:表示制定计划任务。
  • -1:表示列出计划任务。
  • -r:表示删除计划任务。
    下面请跟着创建第一个任务计划,如下所示:
[root@zl_cloud ~]# crontab -e
no crontab for root - using an empty one

这里使用crontab -e来编写任务计划,这实际上是使用vim工具打开了crontab的配置文件,我们 写下如下内容:
01 10 05 06 3 echo "ok" > /root/cron.log
这里每个字段的数字分别表示什么呢?从左到右依次为:分、时、日、月、周和命令行。上例表示在6月5日(这一天必须是星期三)的10点01分执行命令:echo "ok” > /root/cron.log。
命令crontab -e实际上是打开了/var/spool/cron/usemame文件(如果用户是root,则打开的是 /var/spool/cron/root )o打开这个文件使用了vim编辑器,所以保存时在命令行模式下输入:wq即可。但 是请千万不要直接去编辑那个文件,否则会出错,所以一定要使用命令crontab -e来编辑。
查看已经设定的任务计划使用crontab -l命令,如下所示:

[root@zl_cloud ~]# crontab -l
01 10 05 06 3 echo "ok" >/root/cron.log
[root@zl_cloud ~]# 

删除任务计划要使用crontab -r命令,这个删除选项最好还是少用,因为它会一下子把全部计划 都删除掉。如果你想只删除一条计划,可以使用-e选项进入crontab进行编辑。-r选项用法如下所示:

[root@zl_cloud ~]# crontab -r
[root@zl_cloud ~]# crontab -l
no crontab for root
[root@zl_cloud ~]# 

13.6Linux系统服务管理

13.6.1chkconfig 服务管理工具

CentOS 6上的服务管理工具为chkconfig, Linux系统所有的预设服务都可以通过查看/etc/init.d/目 录得到,如下所示:

[root@zl_cloud ~]# ls /etc/init.d/
functions  netconsole  network  README
[root@zl_cloud ~]# 

只有屈指可数的几个文件,这是因为CentOS 7已经不再延续CentOS 6版本的服务管理方案了。但 是我们依然可以继续使用chkconfig这个命令。系统的预设服务都可以通过这样的命令实现:service服务名start|stop|restart。这里的服务名就是/etc/init.d/目录下的这些文件了。启动crond除了可以使用命令service crond start外,还可以使用命令/etc/init.d/crond starto
我们可以使用命令chkconfig -list列出所有的服务及其每个级别的开启状态,如下所示:

[root@zl_cloud ~]# chkconfig --list

注意:该输出结果只显示 SysV 服务,并不包含原生 systemd 服务。SysV 配置数据可能被原生 systemd 配置覆盖。 
      如果您想列出 systemd 服务,请执行 'systemctl list-unit-files'。
      欲查看对特定 target 启用的服务请执行
      'systemctl list-dependencies [target]'。

netconsole      0:关    1:关    2:关    3:关    4:关    5:关    6:关
network         0:关    1:关    2:开    3:开    4:开    5:开    6:关
[root@zl_cloud ~]# 

在这里也会看到一个提示,它提示我们该命令输出的内容并没有包含CentOS 7的原生systemd服 务,而这里仅仅列出来SysV服务。这也是/etc/init.d/目录下面只有一两个启动脚本的根本原因。也就是 说,早期CentOS版本(7之前)采用的服务管理都是SysV,而7换成了systemd。
这里的级别(数字0~6)为系统启动级别(CentOS 7之前版本的用法,而CentOS 7已经不再严格区分级别的概念了),运行级别0、1和6被系统保留。其中0作为shutdown动作,1作为重启至单用户模式,6为重启。在一般的Linux系统实现中,都使用了2、3、4、5几个级别。在CentOS系统中,2表示无NFS支持的多用户模式,3表示完全多用户模式(也是最常用的级别),4保留给用户自定义,5表示图形登录方式。现在我们只是看到了各服务在每个级别下的开启状态,那么如何去更改某级别下的 开启状态呢?

[root@zl_cloud ~]# chkconfig --level 3 network off
[root@zl_cloud ~]# chkconfig --list |grep network
network         0:关    1:关    2:开    3:关    4:开    5:开    6:关
[root@zl_cloud ~]# 

这里用-level指定级别,后面是服务名,然后是off或者on。选项-level后面还可以指定多个级别,如下所示:

[root@zl_cloud ~]# chkconfig --level 345 network off
[root@zl_cloud ~]# chkconfig --list |grep network
network         0:关    1:关    2:开    3:关    4:关    5:关    6:关
[root@zl_cloud ~]# 

另外还可以省略级别,默认是针对级别2、3、4和5操作的,如下所示:

[root@zl_cloud ~]# chkconfig network on
[root@zl_cloud ~]# chkconfig --list |grep network
network         0:关    1:关    2:开    3:开    4:开    5:开    6:关
[root@zl_cloud ~]#

chkconfig还有一个功能,就是可以把某个服务加入系统服务或者删除,即可以使用“chkconfig --add服务名"或者“chkconfig --del服务名“这样的形式,并且可以在chkconfig --list的结果中査找到。

[root@zl_cloud ~]# chkconfig --del network
[root@zl_cloud ~]# chkconfig --list |grep network
[root@zl_cloud ~]# chkconfig --add network
[root@zl_cloud ~]# chkconfig --list |grep network
network         0:关    1:关    2:开    3:开    4:开    5:开    6:关
[root@zl_cloud ~]# 

这个功能常用于把自定义的启动脚本加入到系统服务当中。关于chkconfig工具,就先介绍这么多。

13.6.2systemd服务管理

上一节提到过,CentOS 7不使用SysV而改为systemd了,这是因为systemd支持多个服务并发启动,而SysV只能一个一个地启动,这样最终导致的结果是systemd方式启动会快很多。接下来的知识点也会让你觉得systemd有点复杂。我们不妨对比着chkconfig工具来学习一下systemdo首先是列出系统所有的服务,如下所示:

[root@zl_cloud ~]# systemctl list-units --all --type=service |head
  UNIT                                                  LOAD      ACTIVE   SUB     DESCRIPTION
  auditd.service                                        loaded    active   running Security Auditing Service
  brandbot.service                                      loaded    inactive dead    Flexible Branding Service
  cpupower.service                                      loaded    inactive dead    Configure CPU power related settings
  crond.service                                         loaded    active   running Command Scheduler
  dbus.service                                          loaded    active   running D-Bus System Message Bus
● display-manager.service                               not-found inactive dead    display-manager.service
  dm-event.service                                      loaded    inactive dead    Device-mapper event daemon
  dracut-shutdown.service                               loaded    inactive dead    Restore /run/initramfs
  ebtables.service                                      loaded    inactive dead    Ethernet Bridge Filtering tables
[root@zl_cloud ~]# 

那这些服务对应的启动脚本文件在哪里呢?

[root@zl_cloud ~]# ls /usr/lib/systemd/system/ |head
arp-ethers.service
auditd.service
[email protected]
basic.target
basic.target.wants
blk-availability.service
bluetooth.target
brandbot.path
brandbot.service
console-getty.service
[root@zl_cloud ~]# 

你会发现这个目录下面的文件有点奇怪,有的是目录,有的是文件,有的以.service为后缀,有的以.target为后缀,当然还有其他的格式,这些东西到底是什么?还是先来看与服务相关的知识点吧, 下面是整理的一些常用命令:

#systemctl enable crond.service // 让某个服务开机启动(.service可以省略)
#systemctl disable crond.service // 不让开机启动
#systemctl status crond.service // 查看服务状态
#systemctl start crond.service // 启动某个服务
#systemctl stop crond.service // 停止某个服务
#systemctl restart crond.service // 重启某个服务
#systemctl is-enabled crond //查看某个服务是否开机启动

其实关于服务的用法还有不少,但上面这些就够用了。下面再介绍两个概念,等你看完这部分内容,对于上面不知所以的文件就会有些眉目了。我们先来说一个很重要的概念一unit.刚刚执行命令ls /usr/lib/systemd/system的时候,下面有很多文件,其实可以把它们归类为下面这几大类。

  • service:系统服务。
  • target:多个unit组成的组。
  • device:硬件设备。
  • mount:文件系统挂载点。 口 automount:自动挂载点。
  • path:文件或路径。
  • scope:不是由systemd启动的外部进程。
  • slice:进程组。
  • snapshot: systemd快照。
  • socket:进程间通信的套接字。
  • swap: swap文件。
  • timer:定时器。
    以上每种类型的文件都为一个unit,正是这些unit才组成了系统的各个资源(各个服务、各个设备 等)。下面给大家介绍几个和unit相关的命令:
    # systemctl list-units //列出正在运行(active)的unit
    # systemctl list-units --all //列出所有的unit(包括失败的、inactive的)
    # systemctl list-units --all --state=inactive //列出所有inactive的unit
    # systemctl list-units --all --type=service //列出所有状态的service
    # systemctl list-units --type=service //列出状态为active的service
    # systemctl is-active crond.service // 查看某个unit是否activ
    下面再来看另外一个概念—targeto target类似于CentOS 6里面的启动级别。但target支持多个target同时启动。target其实是多个unit的组合,系统启动说白了就是启动多个unit,为了管理方便,就使用target来管理这些unit。查看当前系统的所有target:
[root@zl_cloud ~]# systemctl list-unit-files --type=target
UNIT FILE                 STATE   
basic.target              static  
bluetooth.target          static  
cryptsetup-pre.target     static  
cryptsetup.target         static  
ctrl-alt-del.target       disabled
default.target            enabled 
emergency.target          static  
final.target              static  
getty-pre.target          static  
getty.target              static  
graphical.target          static  
halt.target               disabled
hibernate.target          static  
hybrid-sleep.target       static  
initrd-fs.target          static  
initrd-root-fs.target     static  
initrd-switch-root.target static  
initrd.target             static  
[root@zl_cloud ~]# 

查看一个target包含的所有unit,如下所示:

[root@zl_cloud ~]# systemctl list-dependencies multi-user.target
multi-user.target
● ├─auditd.service
● ├─brandbot.path
● ├─crond.service
● ├─dbus.service
● ├─irqbalance.service
● ├─kdump.service
● ├─network.service
● ├─NetworkManager.service
● ├─plymouth-quit-wait.service
● ├─plymouth-quit.service
● ├─postfix.service
● ├─rsyslog.service
● ├─sshd.service
● ├─sysstat.service
● ├─systemd-ask-password-wall.path
● ├─systemd-logind.service
● ├─systemd-readahead-collect.service
● ├─systemd-readahead-replay.service
[root@zl_cloud ~]# 

查看系统默认的target:

[root@zl_cloud ~]# systemctl get-default
multi-user.target
[root@zl_cloud ~]#

设置默认的target:

[root@zl_cloud ~]# systemctl set-default multi-user.target
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/multi-user.target.
[root@zl_cloud ~]# 

上面提到的multi-user.target等同于CentOS6的运行级别3,其实还有其他几个target对应0〜6运行 级别,如下表所示。
在这里插入图片描述
介绍完了unitfHtarget,再带着你一起梳理一下service. unit以及target之间的联系:
(1)一个service属于一种unit;
(2)多个unit一起组成了一个target;
(3)一个target里面包含了多个service,你可以查看文件/usr/1 ib/systemd/system/sshd.service里面 [install]部分的内容,它就定义了该service属于哪一个targeto

13.7Linux下的数据备份工具rsync

作为一个系统管理员,数据备份是非常重要的。在Linux系统下数据备份的工具很多,但我只用一种,那就是rsync,从字面意思上可以理解为 remote sync (远程同步)。rsync不仅可以远程同步数据(类似于scp ),而且可以本地同步数据(类似于cp),但不同于cp或scp的一点是,它不会覆盖以前的数据(如果数据已经存在),而是先判断已经存在的数据和新数据的差异,只有数据不同时才会把不相同的部分覆盖。如果你的Linux没有rsync命令, 请使用命令# yum install -y rsync安装。
下面先举一个例子,然后再详细讲解rsync的用法。

[root@zl_cloud ~]# rsync -av /etc/passwd /tmp/1.txt
sending incremental file list
passwd

sent 1,391 bytes  received 35 bytes  2,852.00 bytes/sec
total size is 1,299  speedup is 0.91
[root@zl_cloud ~]# 

上例将会把/etc/passwd同步到/tmp/目录下,并改名为l.txt。如果是远程复制,数据备份就是这样的形式——IP:path,比如192.168.188.128:/root/.具体用法如下:

[root@zl_cloud ~]# rsync -av /etc/passwd 192.168.10.129:/tmp/1.txt 
The authenticity of host '192.168.10.129 (192.168.10.129)' can't be established.
ECDSA key fingerprint is SHA256:qsUEqoNjFR9hnXrwGWsmfFCrLf5LpszuGXSiw+nsunI.
ECDSA key fingerprint is MD5:b1:c9:68:56:39:73:ce:d7:f0:27:71:51:63:a6:55:47.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.129' (ECDSA) to the list of known hosts.
[email protected]'s password: 
sending incremental file list

sent 45 bytes  received 12 bytes  6.00 bytes/sec
total size is 1,299  speedup is 22.79
[root@zl_cloud ~]# 

首次连接时会提示是否要继续连接,我们输入yes继续。当建立连接后,需要输入密码。如果手动执行这些操作比较简单,但若是写在脚本中该怎么办呢?这就涉及添加信任关系了,该部分内容稍后会详细介绍。

13.7.1rsync的命令格式

rsync [OPTION]… SRC DEST
isync [OPTION]… SRC [USER@]HOST:DEST
rsync [OPTION]… [USER@]HOST:SRC DEST
rsync [OPTION]… [USER@]HOST::SRC DEST
rsync [OPTION]… SRC [USER@]HOST::DEST
在前面举的两个例子中,第一个例子为第一种格式,第二个例子为第二种格式。但不同的是,这里并没有加user@host,如果不加默认指的是root。第三种格式是从远程目录同步数据到本地。第四种和第五种格式使用了两个冒号,这种格式和其他格式的验证方式不同。

13.7.2rsync 常用选项

rsync命令各选项的含义如下。

  • -a:这是归档模式,表示以递归方式传输文件,并保持所有属性,它等同于-rlptgoD。 -a选项后面可以跟一个–no-OPTION,表示关闭-rlptgoD中的某一个,比如-a–no-l等同于-rptgoD。
  • -r:表示以递归模式处理子目录。它主要是针对目录来说的,如果单独传一个文件不需要加 -r选项,但是传输目录时必须加。
  • -V:表示打印一些信息,比如文件列表、文件数量等。
  • -l:表示保留软连接。
  • -L:表示像对待常规文件一样处理软连接。如果是SRC中有软连接文件,则加上该选项后, 将会把软连接指向的目标文件复制到DST。
  • -p:表示保持文件权限。
  • -o:表示保持文件属主信息。
  • -g:表示保持文件属组信息。
  • -D:表示保持设备文件信息。
  • -t:表示保持文件时间信息。
  • --delete:表示删除DST中SRC没有的文件。
  • --exclude=PATTERN:表示指定排除不需要传输的文件,等号后面跟文件名,可以是万用字符模式(*.txt)。
  • --progress:表示在同步的过程中可以看到同步的过程状态,比如统计要同步的文件数量、 同步的文件传输速度等。
    □-u:表示把DST中比SRC还新的文件排除掉,不会覆盖。
    □-z:加上该选项,将会在传输过程中压缩
    选项虽然多,但常用的选项也就-a、-V、-z、–delete和–exclude这几个,请牢记它们!下面将会针对这些选项做一系列小试验。

①建立目录和文件

[root@zl_cloud ~]# mkdir rsync
[root@zl_cloud ~]# cd rsync
[root@zl_cloud rsync]# mkdir test1
[root@zl_cloud rsync]# cd test1
[root@zl_cloud test1]# touch 1 2 3 /root/123.txt
[root@zl_cloud test1]# ln -s /root/123.txt ./123.txt
[root@zl_cloud test1]# ls -l
总用量 0
-rw-r--r-- 1 root root  0 4月  13 06:04 1
lrwxrwxrwx 1 root root 13 4月  13 06:04 123.txt -> /root/123.txt
-rw-r--r-- 1 root root  0 4月  13 06:04 2
-rw-r--r-- 1 root root  0 4月  13 06:04 3
[root@zl_cloud test1]# cd ..
[root@zl_cloud rsync]# 

建立这些文件的目的是为后续实验做准备工作。

②使用-a选项

首先来看看-a选项的用法,如下所示:

[root@zl_cloud rsync]# rsync -a test1 test2
[root@zl_cloud rsync]# ls test2
test1
[root@zl_cloud rsync]# ls test2/test1/
1  123.txt  2  3
[root@zl_cloud rsync]# 

这里有一个问题,就是本来想把testl目录直接复制成test2目录,可结果rsync却新建了test2目录, 然后把testl放到test2当中。为了避免这样的情况发生,可以这样做:

[root@zl_cloud rsync]# rm -rf test2
[root@zl_cloud rsync]# rsync -a test1/ test2/
[root@zl_cloud rsync]# ls -l test2/
总用量 0
-rw-r--r-- 1 root root  0 4月  13 06:04 1
lrwxrwxrwx 1 root root 13 4月  13 06:04 123.txt -> /root/123.txt
-rw-r--r-- 1 root root  0 4月  13 06:04 2
-rw-r--r-- 1 root root  0 4月  13 06:04 3
[root@zl_cloud rsync]# 

这里加一个斜杠就好了,所以建议你在使用rsync备份目录时,要养成加斜杠的习惯。前面已经讲了-a选项等同于-rlptgoD,且-a还可以和-no-OPTIN一并使用。下面再来看看-l选项的作用, 如下所示:

[root@zl_cloud rsync]# rsync -av --no-l test1/ test2/
sending incremental file list
created directory test2
skipping non-regular file "123.txt"
./
1
2
3

sent 234 bytes  received 144 bytes  756.00 bytes/sec
total size is 13  speedup is 0.03
[root@zl_cloud rsync]# 

上例中使用了-V选项,跳过了非普通文件123.txt。其实123.txt是一个软连接文件,如果不使用-1 选项,系统则不理会软连接文件。虽然加-1选项能复制软连接文件,但软连接的目标文件却没有复制。 有时我们需要复制软连接文件所指向的目标文件,这又该怎么办呢?

③使用-L选项

  [root@zl_cloud rsync]# rm -rf test2
[root@zl_cloud rsync]# rsync -avL test1/ test2/
sending incremental file list
created directory test2
./
1
123.txt
2
3

sent 265 bytes  received 123 bytes  776.00 bytes/sec
total size is 0  speedup is 0.00
[root@zl_cloud rsync]# ls -l test2/
总用量 0
-rw-r--r-- 1 root root 0 4月  13 06:04 1
-rw-r--r-- 1 root root 0 4月  13 06:04 123.txt
-rw-r--r-- 1 root root 0 4月  13 06:04 2
-rw-r--r-- 1 root root 0 4月  13 06:04 3
[root@zl_cloud rsync]# 
上例加上-L选项就可以把SRC中软连接的目标文件复制到DST。

④使用-u选项

首先查看一下test1/1和test2/1的创建时间(肯定是一样的),然后使用touch修改一下test2/1的创建 时间(此时test2/1要比test1/1的创建时间晚一些)。如果不加-u选项,会把test2/1的创建时间变成和test1/1 一样,如下所示:

[root@zl_cloud rsync]# ll test1/1 test2/1
-rw-r--r-- 1 root root 0 4月  13 06:04 test1/1
-rw-r--r-- 1 root root 0 4月  13 06:04 test2/1
[root@zl_cloud rsync]# 

从上例可以看出二者的创建时间是一样的。下面修改test2/l的创建时间,然后不加-u同步,如下所示:

[root@zl_cloud rsync]# echo "1111" > test2/1
[root@zl_cloud rsync]# ll test2/1
-rw-r--r-- 1 root root 5 4月  13 06:25 test2/1
[root@zl_cloud rsync]# rsync -a test1/1 test2/
[root@zl_cloud rsync]# ll test2/1
-rw-r--r-- 1 root root 0 4月  13 06:04 test2/1
[root@zl_cloud rsync]# 

这里test2/l的创建时间还是和testl/1 一样。下面加上-u选项,如下所示:

[root@zl_cloud rsync]# echo "1111" > test2/1
[root@zl_cloud rsync]# ll test2/1
-rw-r--r-- 1 root root 5 4月  13 06:26 test2/1
[root@zl_cloud rsync]# rsync -avu test1/ test2/
sending incremental file list
./
123.txt -> /root/123.txt

sent 134 bytes  received 22 bytes  312.00 bytes/sec
total size is 13  speedup is 0.08
[root@zl_cloud rsync]# ll test1/1 test2/1
-rw-r--r-- 1 root root 0 4月  13 06:04 test1/1
-rw-r--r-- 1 root root 5 4月  13 06:26 test2/1
[root@zl_cloud rsync]# 

加上-u选项后,不会再把testl/l同步为test2/l 了o

⑤使用–delete选项

首先删除tcstU123.txt,如下所示:

[root@zl_cloud rsync]# rm -f test1/123.txt 
[root@zl_cloud rsync]# ls test1/
1  2  3
[root@zl_cloud rsync]# 

然后把testl/目录同步到test2/S录下,如下所示:

[root@zl_cloud rsync]# rsync -av test1/ test2/
sending incremental file list
./
1

sent 130 bytes  received 38 bytes  336.00 bytes/sec
total size is 0  speedup is 0.00
[root@zl_cloud rsync]# ls test2/
1  123.txt  2  3
[root@zl_cloud rsync]# 

上例中,test2/目录并没有删除123.txt。下面加上一delete选项,示例如下:

[root@zl_cloud rsync]# rsync -av --delete test1/ test2/
sending incremental file list
deleting 123.txt

sent 84 bytes  received 23 bytes  214.00 bytes/sec
total size is 0  speedup is 0.00
[root@zl_cloud rsync]# ls test2/
1  2  3
[root@zl_cloud rsync]# 

这里test2/目录下的123.txt也被删除了。
另外还有一种情况,就是如果在DST中增加文件了,而SRC当中没有这些文件,同步时加上-delete选项后同样会删除新增的文件。如下所示:

[root@zl_cloud rsync]# touch test2/4
[root@zl_cloud rsync]# ls test1/
1  2  3
[root@zl_cloud rsync]# ls test2/
1  2  3  4
[root@zl_cloud rsync]# rsync -a --delete test1/ test2/
[root@zl_cloud rsync]# ls test1/
1  2  3
[root@zl_cloud rsync]# ls test2/
1  2  3
[root@zl_cloud rsync]# 

⑥使用–exclude选项

[root@zl_cloud rsync]# touch test1/4
[root@zl_cloud rsync]# rsync -a --exclude="4" test1/ test2/
[root@zl_cloud rsync]# ls test1/
1  2  3  4
[root@zl_cloud rsync]# ls test2/
1  2  3
[root@zl_cloud rsync]# 

该选项还可以与匹配字符*一起使用,如下所示:

[root@zl_cloud rsync]# touch test1/1.txt test1/2.txt
[root@zl_cloud rsync]# ls test1/
1  1.txt  2  2.txt  3  4
[root@zl_cloud rsync]# rsync -a --progress --exclude="*.txt" test1/ test2/
sending incremental file list
./
4
              0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=0/5)
[root@zl_cloud rsync]# ls test2/
1  2  3  4
[root@zl_cloud rsync]# 

上例中,也使用了-progress选项,它主要是用来观察rsync同步过程状态的。
总而言之,平时你使用rsync同步数据时,使用-a选项基本上就可以达到想要的效果了。当有个别需求时,也会用到–no-OPTION, -u> -L, --delete, --exclude以及–progress等选项。其他选项这里没有介绍,如果在以后的工作中遇到特殊需求,可以査一下rsync的man文档。

13.7.3rsync应用实例

上面列举了许多小案例,都是为了让大家熟悉rsync各个选项的基本用法。在正式试验前,你需要准备两台Linux机器,因为下面的小案例都是从 一台机器复制文件到另一台机器。这里我的两台机器IP地址分别为192.168.188.128和192.168.188.129。

①通过ssh的方式

在之前介绍的rsync的5种命令格式中,第二种和第三种(一个冒号)就属于通过ssh的方式备份数 据。这种方式其实就是让用户登录到远程机器,然后执行rsync的任务:

#rsync -avL test1/ 192.168.188.129:/tmp/test2/
[email protected]'s password:
sending incremental file list
created directory /tmp/test2
./
1
1.txt
2
2.txt
3
4
sent 323 bytes received 129 bytes 100.44 bytes/sec
total size is 0 speedup is 0.00

这种方式就是前面介绍的第二种方式了,是通过ssh复制的数据,需要输入192.168.188.129那台机 器root账户的密码。
当然也可以使用第三种方式复制,如下所示:

#rsync -avL 192.168.188.129:/tmp/test2/ ./test3/
[email protected]*s password:
receiving incremental file list
created directory ./test3
./
1
1.txt
2
2.txt
3
4
sent 128 bytes received 340 bytes 104.00 bytes/sec
total size is 0 speedup is 0.00

以上两种方式如果写入脚本,做备份麻烦,要输入密码,但我们可以通过密钥(不设立密码)验证。下面具体介绍一下通过密钥登录远程主机的方法。
你可以根据以前知识,把128机器上的公钥内容放到129机器下的authorized_keys里面,这样128机器 登录129机器时不再输入密码,如下所示:

#ssh 192.168.188.129
Last login: Mon Mar 6 07:18:16 2017 from 192.168.188.1

现在不用输入密码也可以登录主机129了。下面先从129主机退出来,再从主机128上执行一下 rsync命令试试吧:

#rsync -avL test1/ 192.168.188.129:/tmp/test4/
sending incremental file list
created directory /tmp/test4
./
1
1.txt
2
2.txt
3
4
sent 323 bytes received 129 bytes 904.00 bytes/sec
total size is o speedup is 0.00

②通过后台服务的方式

这种方式可以理解为:在远程主机上建立一个rsync的服务器,在服务器上配置好rsync的各种应用,然后将本机作为rsync的一个客户端连接远程的rsync服务器。下面介绍一下如何配置一台 rsync服务器。
在128主机上建立并配置rsync的配置文件/etc/rsyncd.conf,如下所示(请把你的rsyncd.conf编辑成如下内容):

# vim /etc/rsyncd.conf
port=873
log file=/var/log/rsync.log
pid file=/var/run/rsyncd.pid
address=192.168.188.128
[test]
path=/root/rsync
use chroot=true
max connections=4
read only=no
list=true
uid=root
gid=root
auth users=test
secrets file=/etc/rsyncd.passwd
hosts allow=192.168.188.129

其中配置文件分为两部分:全局配置部分和模块配置部分。全局部分就是几个参数,比如我的 rsyncd.conf中的port、log file> pid file和address都属于全局配置;而[test]以下部分就是模块配置部分了。一个配置文件中可以有多个模块,模块名可自定义,格式就像我的rsyncd.conf中的这样。其实模块中的一些参数(如use chroot、max connections, udi、gid、auth users、secrets file以及 hosts allow都可以配置成全局参数。当然我并未给出所有的参数,你可以通过命令man rsyncd.conf 获得更多信息。
下面就简单解释一下这些参数的作用。

  • port:指定在哪个端口启动rsyncd服务,默认是873端口。
  • log file:指定日志文件。
  • pid file:指定pid文件,这个文件的作用涉及服务的启动、停止等进程管理操作。
  • address:指定启动rsyncd服务的IP。假如你的机器有多个IP,就可以指定由其中一个启动 rsyncd服务,如果不指定该参数,默认是在全部IP上启动。
  • []:指定模块名,里面内容自定义。
  • path:指定数据存放的路径。
  • use chroot true (false:表示在传输文件前,首先chroot到path参数所指定的目录下。这样做的原因是实现额外的安全防护,但缺点是需要roots权限,并且不能备份指向外部的符号连接 所指向的目录文件。默认情况下chroot值为true,如果你的数据当中有软连接文件,建议你设置成false。
  • max connections:指定最大的连接数,默认是0,即没有限制。
  • read only ture|false:如果为true,则不能上传到该模块指定的路径下。
  • list:表示当用户查询该服务器上的可用模块时,该模块是否被列出,设定为true则列出,设定为false则隐藏。
  • uid/gid:指定传输文件时以哪个用户/组的身份传输。
  • auth users:指定传输时要使用的用户名。
  • secrets file:指定密码文件,该参数连同上面的参数如果不指定,则不使用密码验证。注意,该密码文件的权限一定要是600。
  • hosts allow:表示被允许连接该模块的主机,可以是IP或者网段,如果是多个,中间用空格 隔开。
    编辑secrets file并保存后要赋予600权限,如果权限不对,则不能完成同步,如下所示:
#cat /etc/rsyncd.passwd
test:test123
#chmod 600 /etc/rsyncd.passwd

启动rsyncd服务,如下所示:
#rsync --daemon --config=/etc/rsyncd.conf
启动后可以查看一下日志,并查看端口是否启动,如下所示:

#cat /var/log/rsync.log
2020/04/13 08:54:13 [3070] rsyncd version 3.0.9 starting, listening on port 873
#netstat -Inp |grep rsync
tcp 0	0 192.168.188.128:873	0.0.0.0:*	LISTEN 3070/rsync

如果想开机启动rsyncd服务,请把/usr/bin/rsync --daemon --confg=/etc/rsyncd.conf写入 /etc/rc.d/rc.local 文件。
为了不影响实验过程,还需要把两台机器的firewalld服务关闭,并设置为不开机启动,操作过程如下所示:

#systemctl stop firewalld ; systemctl disable firewalld 〃两台机器都执行
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallDl.service.
Removed symlink /etc/systemd/system/basic.target.wants/firewalld.service.
#rsync -avL [email protected]:: test/testl/ /tmp/test5/ 〃129上执行
Password:
receiving incremental file list
created directory /tmp/test5
./
1
1.txt
2
2.txt
3
4
sent 171 bytes received 391 bytes 26.14 bytes/sec
total size is 0 speedup is 0.

刚刚提到了选项use chroot,默认为trueo首先在主机128的/root/rsync/testl/目录下创建一个软连接文件,如下所示:

#ln -s /etc/passwd /root/rsync/test1/test.txt
#ls -1 /root/rsync/testl/test.txt
lrwxrwxrwx 1 root root 11 3月 6 07:47 /root/rsync/testl/test.txt -> /etc/passwd

然后再到主机129上执行同步,如下所示:

# rsync -avL [email protected]::test/test1/ /tmp/test6/
Password:
receiving incremental file list
symlink has no referent: "/test1/test.txt" (in test)
created directory /tmp/test6
./
1
1.txt
2
2.txt
3
4
sent 171 bytes received 450 bytes 177.43 bytes/sec
total size is 0 speedup is 0.00
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1518) [generator=3.0.9]

从上例可以看岀,如果设置use chroot为true,则同步软连接文件会有问题。下面把主机128 的rsync配置文件修改一下,把true改为false,如下所示:

#sed -i 's/use chroot=true/use chroot=false/' /etc/rsyncd.conf
#grep ‘use chroot’ /etc/rsyncd.conf
use chroot=false

然后再到主机129上再次执行同步,如下所示:

#rsync -avL [email protected]::test/testl/ /tmp/test7/
Password:
receiving incremental file list
created directory /tmp/test7
./
1
1.txt
2
2.txt
3
4
test.txt
sent 190 bytes received 2812 bytes 461.85 bytes/sec
total size is 2361 speedup is 0.79

这样问题就解决了。另外,修改完rsyncd.conf配置文件后不需要重启rsyncd服务,这是rsync的一 个特定机制,配置文件是即时生效的。
上面的例子中,我都有输入密码,这意味着我们还是不能写入脚本中自动执行。其实这种方式可以不用手动输入密码,它有两种实现方式。

(1)指定密码文件

在客户端(即主机129)上编辑一个密码文件:

#vim /etc/pass
加入test用户的密码:
#cat /etc/pass
testl23
修改密码文件的权限:
#chmod 600 /etc/pass

在同步时指定密码文件,就可以省去输入密码的步骤,如下所示:

#rsync -avL [email protected]::test/test1/ /tmp/test8/ --password-file=/etc/pass
receiving incremental file list
created directory /tmp/test8
./
1
1.txt
2
2.txt
3
4
test.txt
sent 190 bytes received 2812 bytes 461.85 bytes/sec
total size is 2361 speedup is 0.79

(2)在rsync服务端不指定用户

在服务端(即主机128)上修改配置文件rsyncd.conf,删除关于认证账户的配置项(auth user和 secrets file这两行),如下所示:
#sed -i 's/auth users/#auth users/;s/secrets file/#secrets file/' /etc/rsyncd.conf
上例是在auth users和secrets file这两行的最前面加一个#,这表示将这两行作为注释,使其失去意义。在前面未曾讲过sed的这种用法,它是用分号把两个替换的子命令块替换了。
然后我们再到客户端主机129上进行测试,如下所示:

# rsync -avL [email protected]::test/testl/ /tmp/test9/ 
receiving incremental file list 
created directory /tmp/test9
1
1.txt
2
1.txt
3
4
test.txt
sent 190 bytes received 2812 bytes 461.85 bytes/sec
total size is 2361 speedup is 0.79

注意,这里不用再加test这个用户了,默认是以root的身份复制的。现在登录时已经不需要输入密码了。

13.8Linux 系统日志

日志记录了系统每天发生的各种各样的事情,比如监测系统状况、排查系统故障等。你可以通过日志来检查错误发生的原因,或者受到攻击时攻击者留下的痕迹。日志的主要功能是审计和监测,还可以实时地监测系统状态,监测和追踪侵入者等。

13.8.1/var/log/messages

常査看的日志文件为/var/log/messages,它是核心系统日志文件,包含了系统启动时的引导消息,以及系统运行时的其他状态消息。I/O错误、网络错误和其他系统错误都会记录到这个文件中。 其他信息,比如某个人的身份切换为root,以及用户自定义安装的软件(Apache )的日志也会在这里列出。
通常情况下,/var/log/messages是做故障诊断时首先要查看的文件。那你肯定会说,这么多日志都记录到这个文件中,如果服务器上有很多服务,岂不是这个文件很快就会写得很大?没错,但是系统有一个日志轮询的机制,每星期切换一个日志,切换后的日志名字类似于messages-20200413,会存放在/var/log/目录下面,连同messages一共有5个这样的日志文件。这里的20200413就是日期,它表示日志切割的年月日。在CentOS 5里,这个后缀并不是日期,而是数字1、2、3或4。这是通过logrotate工具的控制来实现的,它的配置文件是/etc/logrotate.conf(如果没有特殊需求,请不要修改这个配置文件)。

[root@zl_cloud ~]# cat /etc/logrotate.conf 
# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
dateext

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
        minsize 1M
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

# system-specific logs may be also be configured here.
[root@zl_cloud ~]# 

这个配置文件里面的内容还是很容易明白的,都带有解释。/var/log/messages是由rsyslogd这个守护进程产生的,如果停止这个服务则系统不会产生/var/log/messages,所以这个服务不要停止。rsyslogd服务的配置文件为/etc/rsyslog.conf,这个文件定义了日志的级别。若没有特殊需求,这个配置文件是不需要修改的,详细内容不再阐述。如果你感兴趣,请使用命令man rsyslog.conf获得更多关于它的信息。

13.8.2dmesg

除了关注/var/log/messages外,你还应该多关注一下dmesg这个命令,它可以显示系统的启动信息。 如果你的某个硬件有问题(比如网卡),用这个命令也是可以看到的:

[root@zl_cloud ~]# dmesg |head
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 3.10.0-327.el7.x86_64 ([email protected]) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) ) #1 SMP Thu Nov 19 22:10:57 UTC 2015
[    0.000000] Command line: BOOT_IMAGE=/vmlinuz-3.10.0-327.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=zh_CN.UTF-8
[    0.000000] Disabled fast string operations
[    0.000000] e820: BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ebff] usable
[    0.000000] BIOS-e820: [mem 0x000000000009ec00-0x000000000009ffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000000dc000-0x00000000000fffff] reserved
[root@zl_cloud ~]# 

13.8.3安全日志

关于安全方面的日志,简单介绍几个命令或者日志。
last命令用来查看登录Linux的历史信息,具体用法如下:

[root@zl_cloud ~]# last |head
root     pts/0        192.168.10.1     Mon Apr 13 05:40   still logged in   
root     pts/0        192.168.10.1     Mon Apr 13 01:27 - 04:50  (03:22)    
root     tty1                          Mon Apr 13 01:27   still logged in   
reboot   system boot  3.10.0-327.el7.x Mon Apr 13 01:27 - 07:42  (06:15)    
root     pts/0        192.168.10.1     Sun Apr 12 22:30 - crash  (02:56)    
root     tty1                          Sun Apr 12 22:30 - crash  (02:56)    
reboot   system boot  3.10.0-327.el7.x Sun Apr 12 22:30 - 07:42  (09:12)    
root     pts/0        192.168.10.1     Wed Apr  8 19:39 - crash (4+02:50)   
root     tty1                          Wed Apr  8 19:39 - crash (4+02:50)   
reboot   system boot  3.10.0-327.el7.x Wed Apr  8 19:38 - 07:42 (4+12:03)   
[root@zl_cloud ~]# 

上例中,从左至右依次为账户名称、登录终端、登录客户端IP、登录日期及时长。显示www.baidu.com的话,是因为之前设定过hosts文件。last命令输出的信息实际上是读取了二进 制日志文件/var/log/wtmp,只是这个文件不能直接使用cat、Vim、head、tail等工具査看。
另外/var/log/secure也是和登录信息有关的日志文件。该日志文件记录验证和授权等方面的信息, 比如ssh登录系统成功或者失败时,相关的信息都会记录在这个日志里。
最后,建议你以后在日常的管理工作中,要养成多看日志的习惯,尤其是一些应用软件的日 志。比如Apache、MySQL、PHP (后续内容会讲到)等常用的软件,看它们的错误日志,可以帮助排查问题以及监控它们的运行状况是否良好。

13.9xargs 与 exec

xargs和exec可以实现相同的功能,exec主要是和find一起配合使用,而xargs比exec的用处更多。

13.9.1xargs应用

在前面的例子中曾经使用过这个命令,现在就来详细介绍一下:

[root@zl_cloud ~]# echo "12121212" >123.txt
[root@zl_cloud ~]# ls 123.txt |xargs cat
12121212
[root@zl_cloud ~]# 

上例表示把管道符前面的输出作为xargs后面的命令的输入。它的好处在于可以把原本两步或者多步才能完成的任务仅用一步完成。xargs常常和find命令一起使用,比如查找当前目录创建时间大于 10天的文件,然后再删除,如下所示:
# find . -mtime +10 |xargs rm

这种应用是最为常见的。xargs后面的rm也可以加选项,当为目录时,就需要加-r选项了。xargs 还有一个神奇的功能,比如我现在要查找当前目录下所有后缀为.txt的文件,然后把这些文件变 成,txt_bako正常情况下必须写脚本才能实现,但是使用xargs就能一步完成,如下所示:

[root@zl_cloud ~]# mkdir testxargs
[root@zl_cloud ~]# cd testxargs
[root@zl_cloud testxargs]# touch 1.txt 2.txt 3.txt 4.txt 5.txt
[root@zl_cloud testxargs]# ls
1.txt  2.txt  3.txt  4.txt  5.txt
[root@zl_cloud testxargs]# ls *.txt |xargs -n1 -i{} mv {} {}_bak
[root@zl_cloud testxargs]# ls
1.txt_bak  2.txt_bak  3.txt_bak  4.txt_bak  5.txt_bak
[root@zl_cloud testxargs]# 

上例中,xargs -nl -i{}类似于for循环,-M表示逐个对象进行处理,-i{}表示用。取代前面的对象,mv {} {}_bak相当于mv l.txt l.txt_bak。建议你记住这个应用,非常实用。

13.9.2exec 应用

使用find命令时,经常使用-exec选项,它可以达到和xargs同样的效果。比如查找当前目录创建时间大于10天的文件并删除,如下所示:
#find . -mtime +10 -exec rm -rf {} \;
这个命令中也是用{}替代前面find出来的文件。后面的\作为;的转义符,否则shell会把分号作为该行命令的结尾。
-exec同样可以实现上面批量更改文件名的需求,如下所示:

[root@zl_cloud testxargs]# ls
1.txt_bak  2.txt_bak  3.txt_bak  4.txt_bak  5.txt_bak
[root@zl_cloud testxargs]# find ./*_bak -exec mv {} {}_bak \;
[root@zl_cloud testxargs]# ls
1.txt_bak_bak  2.txt_bak_bak  3.txt_bak_bak  4.txt_bak_bak  5.txt_bak_bak
[root@zl_cloud testxargs]# 

13.10screen工具介绍

有时我们要执行一个命令或者脚本,需要几小时甚至几天,在这个过程中,如果中途断网或出现其他意外情况怎么办?当然,你可以把命令或者脚本放到后台运行,不过也不保险。下面就介绍两种方法来避免这类状况发生。

13.10.1使用 nohup

首先写一个sleep.sh脚本,然后把它放到后台执行,如下所示:

[root@zl_cloud ~]# cat /usr/local/sbin/sleep.sh 
#! /bin/bash

sleep 1000
[root@zl_cloud ~]# nohup sh /usr/local/sbin/sleep.sh &
[1] 4271
[root@zl_cloud ~]# nohup: 忽略输入并把输出追加到"nohup.out"

[root@zl_cloud ~]# 

上例中,直接在sleep.sh后面加&虽然可以在后台运行,但是当退出该终端时,这个脚本很有可能也会退出。所以在前面加上nohup就没有问题了,执行后会在当前目录下生成一个nohup的文件,它的 作用就是防止进程意外中断,并且会把输出信息记录到nohup文件中。

13.10.2screen 工具的使用

简单来说,screen是一个可以在多个进程之间多路复用一个物理终端的窗口管理器。screen中有会话的概念,用户可以在一个screen会话中创建多个screen窗口,在每一个screen窗口中就像操作一个真实的SSH连接窗口一样。下面介绍screen的一个简单应用。
首先打开一个会话,直接输入screen命令,然后回车进入screen会话窗口。如果你的系统中没有 screen命令,请用命令# yum install -y screen安装。它的使用也很简单,直接输入如下命令,就可以进入一个虚拟终端:
#screen
接着查看已经打开的screen会话,如下所示:

[root@zl_cloud ~]# screen -ls
There is a screen on:
        4317.pts-0.zl_cloud     (Attached)
1 Socket in /var/run/screen/S-root.

[root@zl_cloud ~]# 

==然后按Ctrl+A键,再按d退出该screen会话(只是退出,并没有结束,结束screen会话要按Ctrl+D 键或者输入exit )。退出后如果还想再次登录某个screen会话,可以使用命令sreen -r [screen编号], 这个编号就是上例中那个4317。==如果当前只打开了一个screen会话,后面的编号是可以省略的。当你有某个需要长时间运行的命令,或者脚本时,就打开一个screen会话,然后运行该任务,按Ctrl+A键, 再按d退出会话。这样不影响终端窗口上的任何操作。

猜你喜欢

转载自blog.csdn.net/zhang_ZERO/article/details/105492429