天天看點

Linux之程式管理

程式管理

        • 1.1 什麼是程序
          • 1.1.1 程序與程式
          • 1.1.2 工作管理(job control )
          • 1.1.3 程序管理
          • 1.1.4 特殊檔案與程式
            • 1.1.4.1 具有SUID/SGID權限的指令執行狀态
            • 1.1.4.2 程序資料的檢視
            • 1.1.4.3 查詢程式已打開的檔案

Linux系統是一個多任務的開源作業系統,背景運作着很多的程序。今天我們來學習下程序相關的内容。

在linux系統中,觸發任何一個事件時,系統都會将它定義為一個程序,并且給這個程序配置設定一個PID。

簡單地說,執行一個程式、腳本或指令,就可以觸發一個事件并且取得一個PID。在我看來就是核心讀取磁盤中的一個程式,并且加載到記憶體中,給他配置設定一個程序号PID。總結下來,程序就是一個運作中的程式。

運作bash後會生成一個子shell,檢視其産生的程序
[root@aliyun-hk1 ~]# bash
[root@aliyun-hk1 ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  3819  3817  0  80   0 - 28895 do_wai pts/0    00:00:00 bash
4 S     0  3875  3819  0  80   0 - 26989 hrtime pts/0    00:00:00 sleep
0 S     0  3881  3819  0  80   0 - 26989 hrtime pts/0    00:00:00 sleep
4 S     0  3949  3819  0  80   0 - 28894 do_wai pts/0    00:00:00 bash
0 R     0  3960  3949  0  80   0 - 38312 -      pts/0    00:00:00 ps
           

将一個指令丢到背景去執行,即在指令末尾增加&,就會産生一個job,包括job number,程序id等,這裡的1是job号,3991是程序号。最開始的job狀态是Running,後來執行結束後就自動變成了Done。

[root@aliyun-hk1 ~]# jobs
[root@aliyun-hk1 ~]# sleep 20 &
[1] 3991
[root@aliyun-hk1 ~]# jobs
[1]+  Running                 sleep 20 &
[root@aliyun-hk1 ~]# jobs
[1]+  Done                    sleep 20
[root@aliyun-hk1 ~]#
           

使用CTRL+Z,将目前的工作丢到背景去,是以就會産生一個job number。

[root@aliyun-hk1 ~]# vim hello.js
[1]+  Stopped                 vim hello.js
[root@aliyun-hk1 ~]#
[root@aliyun-hk1 ~]# jobs
[1]+  Stopped                 vim hello.js
[root@aliyun-hk1 ~]#
           

使用jobs檢視後前的背景工作狀态

[root@aliyun-hk1 ~]# jobs
[1]+  Stopped                 vim hello.js
[root@aliyun-hk1 ~]#
           

使用fg将背景作業恢複到前台執行,繼續執行剛才的檔案編輯。

[root@aliyun-hk1 ~]#fg
           

使用bg将在背景而且已暫停執行的job成為運作狀态。

[root@aliyun-hk1 ~]# jobs
[1]-  Stopped                 vim hello.js
[2]   Running                 nohup sleep 20000 &
[3]+  Stopped                 sleep 100000
[root@aliyun-hk1 ~]# bg 3
[3]+ sleep 100000 &
[root@aliyun-hk1 ~]# jobs
[1]+  Stopped                 vim hello.js
[2]   Running                 nohup sleep 20000 &
[3]-  Running                 sleep 100000 &
[root@aliyun-hk1 ~]#
           

管理背景運作中的job:kill

kill -signal job-number
kill -9 job-number 強制删除一個job
kill -15 以正常的程式方式終止一項工作
kill -2 代表由鍵盤執行CTRL+C一樣的操作
           

學習和研究程序管理的意義其實很重大。在linux每個運作的程式,都會運作一個程序,這個程式是否還在運作需要看程序是否存在;如果linux系統的資源使用情況突然異常,需要快速找出這個可疑的程序;如果某個程式寫得不好,導緻有問題的程序存在,也需要找出他;如果有多個重要的使用者級程序在系統運作,如果調整他們的優先級,也很重要。

程序基本資訊檢視,可以使用ps指令

[root@aliyun-hk1 ~]# ps -l  僅檢視自己的bash相關程序
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  6931  6929  0  80   0 - 28895 do_wai pts/0    00:00:00 bash
0 R     0  7000  6931  0  80   0 - 38312 -      pts/0    00:00:00 ps
[root@aliyun-hk1 ~]#
           
[root@aliyun-hk1 ~]# ps aux 列出目前所有在記憶體中的程序
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.6  43532  3420 ?        Ss   Mar15   0:07 /usr/lib/systemd/systemd
root         4  0.0  0.0      0     0 ?        S<   Mar15   0:00 [kworker/0:0H]
root         5  0.0  0.0      0     0 ?        S    Mar15   0:01 [kworker/u2:0]
root         6  0.0  0.0      0     0 ?        S    Mar15   0:01 [ksoftirqd/0]
root         7  0.0  0.0      0     0 ?        S    Mar15   0:00 [migration/0]
           
[root@aliyun-hk1 ~]# ps axjf 檢視程序并且包含程序樹
    1   838   838   838 ?           -1 Ssl      0   1:39 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
 6931  7004  7003  6931 pts/0     7003 S+       0   0:00          \_ grep --color=auto python
    1  1297  1296  1266 ?           -1 Sl       0   2:53 python proxyserver.py 11081
[root@aliyun-hk1 ~]#
           

程序動态資訊檢視,可以使用top指令

輸入top後,預設系統就會列出所有程序的資訊和整體資源的占用情況。
top - 23:14:35 up 11 days, 12:39,  1 user,  load average: 0.00, 0.01, 0.05
Tasks:  71 total,   1 running,  70 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   498664 total,    36480 free,    95232 used,   366952 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   389812 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  975 root      10 -10  127960  10768   6216 S  1.3  2.2 146:08.95 AliYunDun
    1 root      20   0   43532   3420   2104 S  0.0  0.7   0:07.60 systemd
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd
           
檢視某個程序的負載,可以這樣玩
[root@aliyun-hk1 linux-shell-test]# top -d 2 -p 975 
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  0.0 sy,  0.0 ni, 99.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   498664 total,    36232 free,    95160 used,   367272 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   389892 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  975 root      10 -10  127960  10768   6216 S  1.0  2.2 146:13.63 AliYunDun
           
top指令很強大,可以持續監測整個系統的工作狀态,預設情況下5秒更新一次。這個指令今天暫時不展開講了。

程序之間關系的檢視

[root@aliyun-hk1 ~]# pstree
systemd─┬─AliYunDun───23*[{AliYunDun}]
        ├─AliYunDunUpdate───3*[{AliYunDunUpdate}]
        ├─2*[agetty]
        ├─aliyun-service───2*[{aliyun-service}]
        ├─atd
        ├─auditd───{auditd}
        ├─chronyd
        ├─crond
        ├─dbus-daemon
        ├─dhclient
        ├─lvmetad
        ├─nginx───nginx
        ├─polkitd───6*[{polkitd}]
        ├─python───13*[{python}]
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───bash───pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        └─tuned───4*[{tuned}]
[root@aliyun-hk1 ~]#

           

程序的管理和控制

我們要控制某個程序,隻要給他發信号就可以了,程序的唯一辨別符就是程序ID。

通過程序PID來終止程序,文法為:kill -signal PID,例如: kill -9 12306

代号 含義
1 啟動被終止的程序
2 相當于鍵盤輸入CTRL+C來中斷一個程序
9 強制中斷某一個程序
15 等待程序完成後續操作後,結束該程序
17 相當于使用者鍵入CTRL+Z暫停一個程序的執行

通過程序PID來終止程序,文法為:killall [command name],例如:killall -9 httpd

程序的執行順序

Linux是多使用者、多任務的環境,由top輸出的結果我們也可以發現,系統同時間有非常多的程序運作中,隻是絕大部分的程序都在休眠(sleep)狀态而已。作業系統核心,有預設的排程規則,會自動計算出一個“優先執行序”(priority,PRI),這個PRI值越低代表越優先,使用者無法幹預這個PRI。

[robin@aliyun-hk1 linux-shell-test]$ ps -alt
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
4     0   560     1  20   0 110108   824 n_tty_ Ss+  ttyS0      0:00 /sbin/agetty --keep-baud 115200,38400,9600 ttyS0 vt220
4     0   561     1  20   0 110108   820 n_tty_ Ss+  tty1       0:00 /sbin/agetty --noclear tty1 linux
4     0  8614  8612  20   0 115580  2084 do_wai Ss   pts/0      0:00 -bash
4     0  8631  8614  20   0 191784  2340 do_wai S    pts/0      0:00 su - robin
4  1000  8632  8631  20   0 115448  2096 do_wai S    pts/0      0:00 -bash
0  1000  8675  8632  20   0 153248  1500 -      R+   pts/0      0:00 ps -alt
[robin@aliyun-hk1 linux-shell-test]$
           

可以通過Nice來調整,也就是上面的NI,一般他們的關系如下:

PRI(new) = PRI(old) + nice
           

root可以随意調整自己或他人程序的nice值,調整的範圍是-20~19;

一般使用者可以調整的範圍僅為0-19(為了避免搶占系統資源),而且隻能調大,或者初次使用時設定。

新啟動一個程式,并設定nice為-5
[root@aliyun-hk1 ~]# nice -n -5 vi &
[1] 8699
[root@aliyun-hk1 ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  8614  8612  0  80   0 - 28895 do_wai pts/0    00:00:00 bash
4 T     0  8699  8614  0  75  -5 - 31055 do_sig pts/0    00:00:00 vi
0 R     0  8700  8614  0  80   0 - 38312 -      pts/0    00:00:00 ps

[1]+  Stopped                 nice -n -5 vi
[root@aliyun-hk1 ~]#
           

調整現有程序的優先級,nice值重新調整

[root@aliyun-hk1 ~]# renice 10 8699
8699 (process ID) old priority -5, new priority 10
[root@aliyun-hk1 ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  8614  8612  0  90  10 - 28895 do_wai pts/0    00:00:00 bash
4 T     0  8699  8614  0  90  10 - 31055 do_sig pts/0    00:00:00 vi
0 R     0  8718  8614  0  90  10 - 38312 -      pts/0    00:00:00 ps
[root@aliyun-hk1 ~]# renice 9 8699
8699 (process ID) old priority 10, new priority 9
[root@aliyun-hk1 ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  8614  8612  0  90  10 - 28895 do_wai pts/0    00:00:00 bash
4 T     0  8699  8614  0  89   9 - 31055 do_sig pts/0    00:00:00 vi
0 R     0  8720  8614  0  90  10 - 38312 -      pts/0    00:00:00 ps
[root@aliyun-hk1 ~]#
           
因為一般使用者隻能調高nice,即降低優先級,是以我們一般通過調大nice降低非核心任務的優先級,保證核心業務運作的優先級。

系統資源檢視

除了系統程序管理外,我們還需要了解如何查詢其他系統資源,例如:

[root@aliyun-hk1 ~]# free -m free 檢視記憶體使用情況
              total        used        free      shared  buff/cache   available
Mem:            486          93          34           0         359         380
Swap:             0           0           0
           
Linux系統管理記憶體的方式跟windows有很大差異,為了讓使用者的體驗更好,系統性能更好,核心會盡可能使用現有的記憶體,是以如果記憶體幾乎被用光,不要心慌。除非swap開始被大量使用, 才要開始警惕。
[root@aliyun-hk1 ~]# uname -a 核心基本資訊檢視
Linux aliyun-hk1 3.10.0-1062.12.1.el7.x86_64 #1 SMP Tue Feb 4 23:02:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[root@aliyun-hk1 ~]#
           
核心基本資訊主要包括,主機名、核心版本、建立日期、試用的硬體平台等。
[root@aliyun-hk1 ~]# uptime 檢視系統啟動時間及負載
 00:03:22 up 12 days, 13:28,  1 user,  load average: 0.00, 0.01, 0.05
[root@aliyun-hk1 ~]#
           
啟動時間就是系統已經開啟或重新開機多久了,負載就是隻1,5,15分鐘的平均負載。
[root@aliyun-hk1 ~]# netstat -an 檢視網絡資訊
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:11081           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 172.31.200.164:11081    47.103.99.182:53826     ESTABLISHED

           
一般我們最長去使用netstat去判斷某個程序是否開啟了xx監聽端口。
[root@aliyun-hk1 ~]# dmesg |more 分析核心産生的資訊
[    0.000000]   0 base 000080000000 mask 3FFF80000000 uncachable
[    0.000000]   1 disabled
[    0.000000]   2 disabled
[    0.000000]   3 disabled
[    0.000000]   4 disabled
[    0.000000]   5 disabled
[    0.000000]   6 disabled
[    0.000000]   7 disabled
[    0.000000] PAT configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- UC
[    0.000000] found SMP MP-table at [mem 0x000f59f0-0x000f59ff] mapped at [ffffffffff2009f0]
[    0.000000] Base memory trampoline at [ffff9bf500099000] 99000 size 24576
[    0.000000] Using GB pages for direct mapping
[    0.000000] BRK [0x0b270000, 0x0b270fff] PGTABLE
[    0.000000] BRK [0x0b271000, 0x0b271fff] PGTABLE
           

vmstat 檢測系統資源變化,結合top分析系統瓶頸。

他可以動态檢視CPU/記憶體/磁盤/IO等資料。

[root@aliyun-hk1 ~]# 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  34064  67792 300812    0    0     1     2   31    4  0  0 99  0  0
[root@aliyun-hk1 ~]# vmstat 3 每3秒動态輸出一次
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0  34064  67792 300812    0    0     1     2   31    4  0  0 99  0  0
 0  0      0  34064  67800 300812    0    0     0     5  267  875  0  0 99  0  0
^C
           

1.1.4.1 具有SUID/SGID權限的指令執行狀态

普通使用者使用者都有權限通過passwd修改自己的密碼,但是密碼檔案的權限是root,那為什麼普通使用者有權限讀寫呢?因為普通使用者有passwd程式的特殊權限,他在運作passwd程式時,會自動取得一個新的程序與PID,且具有owner的權限,即具有讀寫權限。

密碼檔案的預設權限644,也就是普通使用者隻可以去讀。
[robin@aliyun-hk1 ~]$ ls -alt /etc/passwd
-rw-r--r-- 1 root root 1175 Mar 11 00:07 /etc/passwd
[robin@aliyun-hk1 ~]$

找到passwd程式,并看他的權限,他有SUID權限
[robin@aliyun-hk1 ~]$ whereis passwd
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1.gz
[robin@aliyun-hk1 ~]$ ls -alt /usr/bin/passwd
-rwsr-xr-x 1 root root 27856 Aug  9  2019 /usr/bin/passwd
[robin@aliyun-hk1 ~]$
           

1.1.4.2 程序資料的檢視

其實程序都是加載到記憶體中運作的,而記憶體中的資料又都是寫入到/proc/*這個目錄的。我們當然可以檢視/proc/下面的資料。我們發現目前主機上運作的程序,都是以PID編号命名,存到這裡的。

[robin@aliyun-hk1 ~]$ ls -ltr /proc/
total 0
lrwxrwxrwx  1 root    root                  0 Mar 15 10:34 self -> 10312
-r--r--r--  1 root    root                  0 Mar 15 10:34 swaps
dr-xr-xr-x  9 root    root                  0 Mar 15 10:34 342
dr-xr-xr-x  9 root    root                  0 Mar 15 10:34 362
dr-xr-xr-x  9 root    root                  0 Mar 15 10:34 363
dr-xr-xr-x  9 root    root                  0 Mar 15 10:34 468
dr-xr-xr-x  9 polkitd polkitd               0 Mar 15 10:34 492
dr-xr-xr-x  9 root    root                  0 Mar 15 10:34 496
dr-xr-xr-x  9 dbus    dbus                  0 Mar 15 10:34 503
dr-xr-xr-x  9 chrony  chrony                0 Mar 15 10:34 510

[robin@aliyun-hk1 ~]$ ps -ef|grep 342
root       342     1  0 Mar15 ?        00:00:03 /usr/lib/systemd/systemd-journald
robin    10314 10261  0 22:33 pts/1    00:00:00 grep --color=auto 342
[robin@aliyun-hk1 ~]$
           

這個以PID編号命名的為檔案夾裡,有什麼内容呢?這裡面有好多内容,我們可以先了解下cmdline和environ,前者存儲的是這個程序被啟動的指令串,後者存儲的是程序的環境變量。

[robin@aliyun-hk1 10319]$ ps -ef|grep sleep
robin    10319 10261  0 22:34 pts/1    00:00:00 sleep 100000
robin    10346 10261  0 22:39 pts/1    00:00:00 grep --color=auto sleep
[robin@aliyun-hk1 10319]$ cd /proc/10319/
[robin@aliyun-hk1 10319]$ ll
total 0
dr-xr-xr-x 2 robin robin 0 Mar 28 22:35 attr
-rw-r--r-- 1 robin robin 0 Mar 28 22:35 autogroup
-r-------- 1 robin robin 0 Mar 28 22:35 auxv
-r--r--r-- 1 robin robin 0 Mar 28 22:34 cgroup
--w------- 1 robin robin 0 Mar 28 22:35 clear_refs
-r--r--r-- 1 robin robin 0 Mar 28 22:34 cmdline
-rw-r--r-- 1 robin robin 0 Mar 28 22:35 comm
-rw-r--r-- 1 robin robin 0 Mar 28 22:35 coredump_filter
-r--r--r-- 1 robin robin 0 Mar 28 22:35 cpuset
lrwxrwxrwx 1 robin robin 0 Mar 28 22:34 cwd -> /proc/342
-r-------- 1 robin robin 0 Mar 28 22:35 environ
.....

[robin@aliyun-hk1 10319]$ cat cmdline
sleep100000[robin@aliyun-hk1 10319]$ cat environ
XDG_SESSION_ID=2314HOSTNAME=aliyun-hk1TERM=xtermSHELL=/bin/bashHISTSIZE=1000SSH_CLIENT=
......
           
檔案名 檔案内容
/proc/cmdline 加載kernel時所執行的相關參數
/proc/cpuinfo 本機CPU相關的資訊,例如頻率、類型、數量
/proc/devices 記錄了系統各個主要裝置的代号
/proc/filesystems 目前系統上已加載的檔案系統
/proc/loadavg top uptime指令中負載的三個平均值就記錄在這裡
/proc/meminfo 查閱記憶體資訊,相當于free的作用
/proc/mounts 查閱系統已經挂載的資料,相當于mount
/proc/swaps 記錄swap内容使用的檔案系統
/proc/version 記錄核心的版本
不加參數,預設列印PID号
[robin@aliyun-hk1 ~]$ fuser nohup.out
/home/robin/nohup.out: 10319
[robin@aliyun-hk1 ~]$ ps -ef|grep 10319
robin    10319 10261  0 22:34 pts/1    00:00:00 sleep 100000
robin    10380 10261  0 22:58 pts/1    00:00:00 grep --color=auto 10319
[robin@aliyun-hk1 ~]$

加參數可以擷取更多的程序資訊
[robin@aliyun-hk1 ~]$ fuser -uv nohup.out
                     USER        PID ACCESS COMMAND
/home/robin/nohup.out:
                     robin     10319 F.... (robin)sleep
[robin@aliyun-hk1 ~]$
           
找出robin使用者下,被程式打開的所有檔案
[root@aliyun-hk1 ~]# lsof -u robin|wc -l
108
[root@aliyun-hk1 ~]#
           

繼續閱讀