程式管理
-
-
-
- 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 ~]#