天天看點

Linux系統管理——程序和計劃任務

1、程序

    程序的管理是核心的重要功能之一,了解和熟練的完成程序管理是系統安全、性能效率優化的基礎。

1.1、程序的性能及功能

    核心的功用:    
        程序管理、檔案系統、網絡功能、記憶體管理、驅動程式、 安
        全功能等。      

程序的性質:

    Process:     
        運作中的程式的一個副本,是被載入記憶體的一個指令集合程序ID(Process ID,PID)号碼被用來标記各個程序
        UID、 GID、和SELinux語境決定對檔案系統的存取和通路權限;
    
        通常從執行程序的使用者來繼承;
        存在生命周期。      

1.2、程序的建立

    程序建立:
        init:第一個程序;上帝程序。
        程序之間存在父子關系。
    
    程序:
        都由其父程序建立,CoW(寫時複制);
        fork(), clone()      

1.3、程序的基本狀态與切換

Linux系統管理——程式和計劃任務

程序的基本狀态:

    建立狀态:    
        程序在建立時需要申請一個空白PCB(process
        control block程序控制塊),向其中填寫控制和管理程序的信
        息,完成資源配置設定。如果建立工作無法完成,比如資源無法滿
        足,就無法被排程運作,把此時程序所處狀态稱為建立狀态;
    
    就緒狀态:
        程序已經準備好,已配置設定到所需資源,隻要配置設定到
        CPU就能夠立即運作;
    
    執行狀态:程序處于就緒狀态被排程後,程序進入執行狀态;
    
    阻塞狀态:
        正在執行的程序由于某些事件(I/O請求,申請緩
        存區失敗)而暫時無法運作,程序受到阻塞。在滿足請求時進
        入就緒狀态等待系統調用;
    
    終止狀态:
        程序結束,或出現錯誤,或被系統終止,進入終止
        狀态。無法再執行;      

1.4、程序優先級

    系統優先級:
        數字越小,優先級越高;
        0-139(CentOS4,5):各有140個運作隊列和過期隊列;
        0-98,99(CentOS6);
    實時優先級: 99-0 值最大優先級最高;
    nice值:-20到19,對應系統優先級100-139或99;
    
    Big O:時間複雜度,用時和規模的關系
    O(1), O(logn), O(n)線性, O(n^2)抛物線, O(2^n)      

2、系統管理工具

Linux系統狀态的檢視及管理工具:
    pstree, ps, pidof,pgrep, top, htop, glance, pmap, vmstat, dstat, kill,
    pkill, job, bg, fg, nohup      

2.1、pstree指令

pstree - display a tree of processes

[[email protected] ~]$pstree
init─┬─abrtd
     ├─acpid
     ├─atd
     ├─auditd───{auditd}
     
[[email protected] ~]$pstree -p
init(1)─┬─abrtd(2237)
        ├─acpid(1698)
        ├─atd(2279)
        ├─auditd(1586)───{auditd}(1587)
        ├─console-kit-dae(2310)─┬─{console-kit-da}(2311)
        │                       ├─{console-kit-da}(2312)      

2.2、ps指令

ps: process state;
ps - report a snapshot of the current processes;      
Linux系統各程序的相關資訊均儲存在/proc/PID目錄下的各檔案中;      
ps [OPTION]...
    支援三種選項:
        UNIX選項 如-A -e
        BSD選項 如a
        GNU選項 如--help      

常用選項:

選項:預設顯示目前終端中的程序    
    • a 選項包括所有終端中的程序
    • x 選項包括不連結終端的程序
    • u 選項顯示程序所有者的資訊
    • f 選項顯示程序樹,相當于 --forest
    • k|--sort 屬性 對屬性排序,屬性前加- 表示倒序
    • o 屬性… 選項顯示定制的資訊 pid、 cmd、 %cpu、 %mem
    • L 顯示支援的屬性清單      
    -C cmdlist     指定指令,多個指令用,分隔
    -L 顯示線程
    -e: 顯示所有程序,相當于-A
    -f: 顯示完整格式程式資訊
    -F: 顯示更完整格式的程序資訊
    -H: 以程序層級格式顯示程序相關資訊
    -u userlist 指定有效的使用者ID或名稱
    -U userlist 指定真正的使用者ID或名稱
    -g gid或groupname 指定有效的gid或組名稱
    -G gid或groupname 指定真正的gid或組名稱
    -p pid 顯示指pid的程序
    --ppid pid 顯示屬于pid的子程序
    -M 顯示SELinux資訊,相當于Z      

    輸出屬性:

        VSZ: Virtual memory SiZe    ,虛拟記憶體集,線性記憶體
        RSS: ReSident Size, 常駐記憶體集
        STAT:程序狀态
            R:running
            S: interruptable sleeping
            D: uninterruptable sleeping
            T: stopped
            Z: zombie
            +: 前台程序
            l: 多線程程序
            L:記憶體分頁并帶鎖
            N:低優先級程序
            <: 高優先級程序
            s: session leader,會話(子程序)發起者
        ni: nice值
        pri: priority 優先級
        psr: processor CPU編号
        rtprio: 實時優先級      
示例:
    ps axo pid,cmd,psr,ni,pri,rtprio      
常用組合:
    aux
    -ef
    -eFH
    -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,comm
    axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm      

2.2.1、示例

查詢你擁有的所有程序:
ps -x
顯示指定使用者名(RUID)或使用者ID的程序:
ps -fU apache
ps -fu 48
顯示指定使用者名(EUID)或使用者ID的程序:
ps -fu wang
ps -fu 1000
檢視以root使用者權限(實際和有效ID)運作的每個程序:
ps -U root -u root
列出某個組擁有的所有程序(實際組ID:RGID或名稱):
ps -fG nginx

列出有效組名稱(或會話)所擁有的所有程序:
ps -fg mysql
ps -fG 27
通過程序ID來顯示所屬的程序:
ps -fp 1234
以父程序ID來顯示其下所有的程序,如顯示父程序為1154的
所有程序:
ps -f --ppid 1234
顯示指定PID的多個程序:
ps -fp 1204,1239,1263
要按tty顯示所屬程序:
ps -ft pst/0

以程序樹顯示系統中的程序如何互相連結:
ps -e --forest
以程序樹顯示指定的程序
ps -f --forest -C sshd
ps -ef --forest | grep -v grep | grep sshd
要顯示一個程序的所有線程,将顯示LWP(輕量級程序)以及
NLWP(輕量級程序數)列:
ps -fL -C nginx
要列出所有格式說明符:
ps L
檢視程序的PID,PPID,使用者名和指令:
ps -eo pid,ppid,user,cmd

自定義格式顯示檔案系統組,ni值開始時間和程序的時間:
ps -p 1234 -o pid,ppid,fgroup,ni,lstart,etime
使用其PID查找程序名稱:
ps -p 1244 -o comm=
要以其名稱選擇特定程序,顯示其所有子程序
ps -C sshd,bash
查找指定程序名所有的所屬PID,在編寫需要從std輸出或文
件讀取PID的腳本時這個參數很有用:
ps -C httpd,sshd -o pid=
檢查一個程序的執行時間
ps -eo comm,etime,user | grep nginx


查找占用最多記憶體和CPU的程序:
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem |
head
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head
顯示安全資訊:
ps -eM
ps --context
使用以下指令以使用者定義的格式顯示安全資訊。
ps -eo euser,ruser,suser,fuser,f,comm,label
使用watch實用程式執行重複的輸出以實作對就程進行實時的
監視,如下面的指令顯示每秒鐘的監視:
watch -n 1 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-
%mem | head'      

2.2.2、程序優先級

程序優先級調整:
    靜态優先級:100-139
    程序預設啟動時的nice值為0,優先級為120
    隻有根使用者才能降低nice值(提高優先性)      
nice指令:
    nice [OPTION] [COMMAND [ARG]...]
renice指令:
    renice [-n] priority pid...
檢視:
    ps axo pid,comm,ni      

2.2.3、搜尋程序

最靈活:ps 選項 | 其它指令
按預定義的模式:pgrep
    pgrep [options] pattern
    -u uid: effective user,生效者
    -U uid: real user,真正發起運作指令者
    -t terminal: 與指定終端相關的程序
    -l: 顯示程序名
    -a: 顯示完整格式的程序名
    -P pid: 顯示指定程序的子程序
按确切的程式名稱:/sbin/pidof
    pidof bash      

2.3、系統工具uptime

顯示目前時間,系統已啟動的時間、目前上線人數,系統平
均負載(1、 5、 10分鐘的平均負載,一般不會超過1)      
系統平均負載:
    指在特定時間間隔内運作隊列中的平均程序數;

通常每個CPU核心的目前活動程序數不大于3,那麼系統
的性能良好。 如果每個CPU核心的任務數大于5,那麼此
主機的性能有嚴重問題;

如果linux主機是1個雙核CPU,當Load Average 為6的
時候說明機器已經被充分使用;      
[[email protected] ~]$uptime
 14:30:06 up  4:32,  3 users,  load average: 0.00, 0.00, 0.00      

2.4、程序管理工具top

top:有許多内置指令:
    排序:
        P:以占據的CPU百分比,%CPU
        M:占據記憶體百分比,%MEM
        T:累積占據CPU時長,TIME+
    首部資訊顯示:
        uptime資訊:l指令
        tasks及cpu資訊:t指令
        cpu分别顯示:1 (數字)
        memory資訊:m指令
    退出指令:q
    修改重新整理時間間隔:s
    終止指定程序:k
    儲存檔案:W      
    欄位資訊簡介    
        us:使用者空間
        sy:核心空間
        ni:調整nice時間
        id:空閑
        wa:等待IO時間
        hi:硬中斷
        si:軟中斷(模式切換)
        st:虛拟機偷走的時間      
選項:
    -d #: 指定重新整理時間間隔,預設為3秒
    -b: 全部顯示所有程序
    -n #: 重新整理多少次後退出      
[[email protected] ~]$top
top - 14:30:37 up  4:32,  3 users,  load average: 0.00, 0.00, 0.00
Tasks: 157 total,   1 running, 156 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.1%sy,  0.0%ni, 99.9%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1004112k total,   597308k used,   406804k free,    88384k buffers
Swap:  1048572k total,        0k used,  1048572k free,   206356k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                    
  2107 mysql     20   0  988m 161m 5384 S  0.3 16.5   0:16.95 mysqld                                      
  3210 root      20   0 15036 1272  944 R  0.3  0.1   0:00.01 top                                         
     1 root      20   0 19348 1556 1236 S  0.0  0.2   0:01.52 init      
擴充:
    htop指令:EPEL源
    選項:
        -d #: 指定延遲時間;
        -u UserName: 僅顯示指定使用者的程序
        -s COLUME: 以指定字段進行排序
    子指令:
        s: 跟蹤標明程序的系統調用
        l: 顯示標明程序打開的檔案清單
        a:将標明的程序綁定至某指定CPU核心
        t: 顯示程序樹      

2.5、vmstat指令

虛拟記憶體資訊
vmstat [options] [delay [count]]
vmstat 2 5      
procs:
    r:可運作(正運作或等待運作)程序的個數,和核心數有關
    b:處于不可中斷睡眠态的程序個數(被阻塞的隊列的長度)
memory:
    swpd: 交換記憶體的使用總量
    free:空閑實體記憶體總量
    buffer:用于buffer的記憶體總量
    cache:用于cache的記憶體總量
swap:
    si:從磁盤交換進記憶體的資料速率(kb/s)
    so:從記憶體交換至磁盤的資料速率(kb/s)      
io:
    bi:從塊裝置讀入資料到系統的速率(kb/s)
    bo: 儲存資料至塊裝置的速率
system:
    in: interrupts 中斷速率,包括時鐘
    cs: context switch 程序切換速率
cpu:
    us:Time spent running non-kernel code
    sy: Time spent running kernel code
    id: Time spent idle. Linux 2.5.41前,包括IO-wait time.
    wa: Time spent waiting for IO. 2.5.41前,包括in idle.
    st: Time stolen from a virtual machine. 2.6.11前, unknown.      
選項:
    -s: 顯示記憶體的統計資料      
[[email protected] ~]$vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 406804  88384 206392    0    0     4     1   10   14  0  0 100  0  0	      
[[email protected] ~]$vmstat -s
      1004112  total memory
       595632  used memory
       336248  active memory
       147916  inactive memory
       408480  free memory
        88384  buffer memory
       206428  swap cache
      1048572  total swap      

2.6、iostat指令

iostat:統計CPU和裝置IO資訊

示例:iostat 1 10      
[[email protected] ~]$iostat
Linux 2.6.32-696.el6.x86_64 (rootdns) 	01/21/2018 	_x86_64_	(4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.01    0.00    0.06    0.17    0.00   99.76

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               0.66        29.84         9.79     536260     175890
scd0              0.01         0.64         0.00      11488          0
dm-0              0.06         0.96         0.05      17298        848      

2.7、pmap指令

    pmap指令:程序對應的記憶體映射;
    
    pmap [options] pid [...]
    -x: 顯示詳細格式的資訊
    示例:pmap 1
    
    另外一種實作:
    cat /proc/PID/maps      
[[email protected] ~]$pmap 1797
1797:   /usr/sbin/sshd
00007f286e56c000     52K r-x--  /lib64/libnss_files-2.12.so
00007f286e579000   2044K -----  /lib64/libnss_files-2.12.so
00007f286e778000      4K r----  /lib64/libnss_files-2.12.so
00007f286e779000      4K rw---  /lib64/libnss_files-2.12.so
00007f286e77a000     28K r-x--  /lib64/librt-2.12.so
00007f286e781000   2044K -----  /lib64/librt-2.12.so      
[[email protected] ~]$pmap -x  1797
1797:   /usr/sbin/sshd
Address           Kbytes     RSS   Dirty Mode   Mapping
00007f286e56c000      52       0       0 r-x--  libnss_files-2.12.so
00007f286e579000    2044       0       0 -----  libnss_files-2.12.so
00007f286e778000       4       4       4 r----  libnss_files-2.12.so
00007f286e779000       4       4       4 rw---  libnss_files-2.12.so
00007f286e77a000      28       0       0 r-x--  librt-2.12.so
00007f286e781000    2044       0       0 -----  librt-2.12.so      

2.8、glances指令

EPEL源

glances [-bdehmnrsvyz1] [-B bind] [-c server] [-C conffile] [-p port] [-Ppassword] [--password] [-t refresh] [-f file] [-o output]      
内建指令:
    a Sort processes automatically     l Show/hide logs
    c Sort processes by CPU%           b Bytes or bits for network I/O
    m Sort processes by MEM%           w Delete warning logs
    p Sort processes by name           x Delete warning and critical logs
    i Sort processes by I/O rate       1 Global CPU or per-CPU stats
    d Show/hide disk I/O stats         h Show/hide this help screen
    f Show/hide file system stats      t View network I/O as combination
    n Show/hide network stats          u View cumulative network I/O
    s Show/hide sensors stats          q Quit (Esc and Ctrl-C also work)
    y Show/hide hddtemp stats      
常用選項:
    -b: 以Byte為機關顯示網卡資料速率
    -d: 關閉磁盤I/O子產品
    -f /path/to/somefile: 設定輸入檔案位置
    -o {HTML|CSV}:輸出格式
    -m: 禁用mount子產品
    -n: 禁用網絡子產品
    -t #: 延遲時間間隔
    -1:每個CPU的相關資料單獨顯示      
C/S模式下運作glances指令

    伺服器模式:
    glances -s -B IPADDR
    IPADDR: 指明監聽的本機哪個位址
    
    用戶端模式:
    glances -c IPADDR
    IPADDR:要連入的伺服器端位址      

2.9、dstat指令

:系統資源統計,代替vmstat,iostat
dstat [-afv] [options..] [delay [count]]

    -c: 顯示cpu相關資訊
    -C #,#,...,total
    -d: 顯示disk相關資訊
    -D total,sda,sdb,...
    -g:顯示page相關統計資料
    -m: 顯示memory相關統計資料
    -n: 顯示network相關統計資料
    -p: 顯示process相關統計資料
    -r: 顯示io請求相關的統計資料
    -s: 顯示swapped相關的統計資料
    --tcp
    --udp
    --unix
    --raw
    --socket
    --ipc
    --top-cpu:顯示最占用CPU的程序
    --top-io: 顯示最占用io的程序
    --top-mem: 顯示最占用記憶體的程序
    --top-latency: 顯示延遲最大的程序      

2.10、iotop

iotop指令是一個用來監視磁盤I/O使用狀況的top類工具。

iotop具有與top相似的UI,其中包括PID、使用者、 I/O、程序

等相關資訊。可檢視每個程序是如何使用IO

互動按鍵:
    left和right方向鍵:改變排序
    r:反向排序
    o:切換至選項--only
    p:切換至--processes選項
    a:切換至--accumulated選項
    q:退出。
    i:改變線程的優先級      
[[email protected] ~]$iotop
Total DISK READ: 0.00 B/s | Total DISK WRITE: 0.00 B/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                    
    1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init
    2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
    3 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/0]
    4 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
    5 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [stopper/0]
    6 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [watchdog/0]
    7 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/1]
    8 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [stopper/1]
    9 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/1]
   10 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [watchdog/1]      

2.11、kill指令

    向程序發送控制信号,以實作對程序管理,每個信号對應一個數字,    
    信号名稱以SIG開頭(可省略),不區分大小寫;
    
    顯示目前系統可用信号: kill –l,trap -l
    常用信号:man 7 signal      
[[email protected] ~]$kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	      
指定信号的方法:
    (1) 信号的數字辨別:1, 2, 9
    (2) 信号完整名稱:SIGHUP (3) 信号的簡寫名稱:HUP      
按PID:
    kill [-SIGNAL] pid …
    kill –n SIGNAL pid;kill –s SIGNAL pid

按名稱:killall [-SIGNAL] comm…

按模式:pkill [options] pattern
    -SIGNAL
    -u uid: effective user,生效者
    -U uid: real user,真正發起運作指令者
    -t terminal: 與指定終端相關的程序
    -l: 顯示程序名(pgrep可用)
    -a: 顯示完整格式的程序名(pgrep可用)
    -P pid: 顯示指定程序的子程序      

3、任務計劃

    Linux任務計劃、周期性任務執行未來的某時間點執行一次任務;
    
    at:一次性任務計劃;
    batch:系統自行選擇空閑時間去執行此處指定的任務周期性運作某任務;
    cron:系統計劃任務,或者使用者任務計劃;      

3.1、at

包:at
 at指令:at [option] TIME
 常用選項:
-V 顯示版本資訊:
-l: 列出指定隊列中等待運作的作業;相當于atq
-d: 删除指定的作業;相當于atrm
-c: 檢視具體作業任務
-f /path/from/somefile:從指定的檔案中讀取任務
-m:當任務被完成之後,将給使用者發送郵件,即使沒有标準輸出      
注意:作業執行指令的結果中的标準輸出和錯誤以郵件通知給相關使用者      
執行方式:
    1)互動式 2)輸入重定向 3)at –f 檔案      
依賴與atd服務,需要啟動才能實作at任務;at隊列存放在/var/spool/at目錄中      
/etc/at.{allow,deny}控制使用者是否能執行at任務:

    白名單:/etc/at.allow 預設不存在,隻有該檔案中的使用者
    才能執行at指令;
    
    黑名單:/etc/at.deny 預設存在,拒絕該檔案中使用者執行
    at指令,而沒有在at.deny 檔案中的使用者則可執行;
    
    如果兩個檔案都不存在,隻有 root 可以執行 at 指令      

3.2、cron

周期性任務計劃:cron

相關的程式包:

    cronie: 主程式包,提供crond守護程序及相關輔助工具;
    cronie-anacron:
        cronie的補充程式,用于監控cronie任務執行狀況,
        如cronie中的任務在過去該運作的時間點未能正常
        運作,則anacron會随後啟動一次此任務;
        
    crontabs:包含CentOS提供系統維護任務      
確定crond守護處于運作狀态:
    CentOS 7:
    systemctl status crond
    CentOS 6:
    service crond status
    
計劃周期性執行的任務送出給crond,到指定時間會自動運作
系統cron任務:系統維護作業
    /etc/crontab

使用者cron任務:
    crontab指令

日志:/var/log/cron      
詳情參見 man 5 crontab

# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR
sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed

例如:晚上9點10分運作echo指令
10 21 * * * centos /bin/echo "Howdy!"

@reboot Run once after reboot.
@yearly 0 0 1 1 *
@annually 0 0 1 1 *
@monthly 0 0 1 * *
@weekly 0 0 * * 0
@daily 0 0 * * *
@hourly 0 * * * *      
系統的計劃任務:
    /etc/crontab
    /etc/cron.d/ 配置檔案
    /etc/cron.hourly/ 腳本
    /etc/cron.daily/ 腳本
    /etc/cron.weekly/ 腳本
    /etc/cron.monthly/腳本      

轉載于:https://blog.51cto.com/mjunetwslinux/2067441