歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux技術

第17章 程序管理與SELinux初探

基本概念

程序:通常為二進制程序放置在存儲媒介中(如硬盤、光盤、軟盤、磁帶等),以物理文件的形式存在。進程:程序被觸發後,執行者的權限與屬性、程序的程序代碼與所需數據等都會加載到內存中,操作系統並給予這個內存內的單元一個標識符(PID),可以說,進程就是一個正在進行中的程序。

系統或網絡服務:常駐在內存的進程。通常都是負責一些系統所提供的功能以服務用戶各項任務,因此這些常駐進程就會被我們稱為服務(daemon)。主要為系統本身所需要的服務和負責網絡聯機的服務。而網絡服務被執行後,它會啟動一個可以負責網絡監聽的端口,以提供外部客戶端的鏈接請求。

工作管理

概述

這個工作管理是用在bash環境下的,也就是說:當我們登錄系統取得bash shell 之後,在單一終端機下同時進行多個工作的行為管理。前台:你可以控制與執行命令的這個環境稱為前台(foreground)的工作;

後台:可以自行運行的工作,無法使用ctrl+c終止它,可使用bg/fg調用該工作;

後台中執行的進程不能等待terminal/shell的輸入(input)。即不能與用戶互動,比如vim可以放在後台掛起,但絕對不能在後台裡面執行。

前台與後台

直接將程序放在後台: &

[code][root@localhost ~]# tar -zpcf /temp/etc.tar.gz  /etc &
這樣仍會有輸出輸入到屏幕

數據流重定向後放入後台運行

[code][root@localhost ~]# tar -zpcf /temp/etc.tar.gz  /etc  > /dev/null 2>&1 &
[1]  8400   <==[job number] PID

[root@localhost ~]# jobs
[1]  + running    python rap_worker_post.py > /dev/null 2>&1

將當前的工作丟到後台中“暫停”:ctrl+z

[code][root@localhost ~]# vim ~/.bashrc
#在vim的一般模式下,按下ctrl+z
[1]+ Stopped     

[root@localhost ~]# jobs
[1]  - running    python rap_worker_post.py > /dev/null 2>&1
[2]  + suspended  vim .bashr

查看目前的後台工作狀態 :jobs -l

[code][root@localhost ~]# jobs -l
[1]  - 55019 running    python rap_worker_post.py > /dev/null 2>&1
[2]  + 55182 suspended  vim .bashrc
+:表示最近被放到後台的工作號碼,也是fg命令默認取的工作

-:表示最近最後第二個被放置到後台中的工作號碼。

將後台工作拿到前台來處理:fg

[code][root@localhost ~]# fg  <==默認取出+的工作
[root@localhost ~]# fg %1  <==直接取規定的工作號碼

讓程序在後台運行:bg

[code][root@localhost ~]# find / -name elasticsearch
#ctrl+z放到後台暫停
[root@localhost ~]# jobs
[1]    running    python rap_worker_post.py > /dev/null 2>&1
[2]  - suspended  vim .bashrc
[3]  + suspended  find / -name elasticsearch

[root@localhost ~]# bg %3;jobs    <==將任務3在後台中運行,任務運行完後會自動從jobs中消失
[1]    running    python rap_worker_post.py > /dev/null 2>&1
[2]  + suspended  vim .bashrc
[3]  - running    find / -name elasticsearch

終止後台任務:kill

kill -signal %jobnumber-1: 重新讀取一次參數的配置文件(類似reload);

-2:代表與由鍵盤輸入ctrl+c同樣的操作;

-9:立刻強制刪除一個工作;

-15:以正常的程序方式終止一項工作。

[code][root@localhost ~]# kill -9 %1 <==殺掉工作1
-9與-15,兩者不同。舉例來說,在用vim的時候,會產生一個.filename.swap文件,使用-15會刪除這個.filename.swap,但使用-9時,由於vim會被強制刪除掉,因此.filename.swap會繼續存在文件系統中。

另外,kill後面接的數字默認是PID,如果想要管理bahs的工作控制,要加上%數字。

脫機管理:nohup/setsid/&

場景: 如果只是臨時有一個命令需要長時間運行,即脫離當前shell客戶端後,仍可以保證它在後台穩定運行呢?

解決方法: 我們知道,當用戶注銷(logout)或者網絡斷開時,終端會收到 HUP(hangup)信號從而關閉其所有子進程。因此,我們的解決辦法就有兩種途徑:要麼讓進程忽略 HUP 信號,要麼讓進程運行在新的會話裡從而成為不屬於此終端的子進程。

1、nohup

[code][root@localhost ~]# nohup ping www.baidu.com
[1] 56648
nohup: 忽略輸入並把輸出追加到"nohup.out"  

[root@localhost ~]# jobs
[1]  + running    nohup ping www.ibm.com

[root@localhost ~]# ps -ef|grep ibm
root     56648 56577  0 16:34 pts/9    00:00:00 ping www.ibm.com
當斷開當前shell客戶端,重新連接後

[code][root@localhost ~]# jobs   <==此時執行jobs任務為空
[root@localhost ~]# ps -ef|grep ibm
root     56648     1  0 16:34 ?        00:00:00 ping www.ibm.com   <==注意這裡父進程變成了1
默認的標准輸出和標准錯誤缺省會被重定向到當前目錄的nohup.out文件中。一般我們可在結尾加上”&”來將命令同時放入後台運行,也可用> filename 2>&1 來更改缺省的重定向文件名。

[code][root@localhost ~]# nohup ping www.baidu.com > /dev/null 2>&1 &
[root@localhost ~]# [1] 56140
[root@localhost ~]# ps -ef |grep 56140
root     56140 55516  0 16:13 pts/9    00:00:00 ping www.baidu.com

2、setsid

nohup 無疑能通過忽略 HUP 信號來使我們的進程避免中途被中斷,但如果我們換個角度思考,如果我們的進程不屬於接受 HUP 信號的終端的子進程,那麼自然也就不會受到 HUP 信號的影響了。setsid 就能幫助我們做到這一點。讓我們先來看一下 setsid 的幫助信息:

[code]SETSID(8)                 Linux Programmer’s Manual                 SETSID(8)

NAME
       setsid - run a program in a new session

SYNOPSIS
       setsid program [ arg ... ]

DESCRIPTION
       setsid runs a program in a new session.
可見 setsid 的使用也是非常方便的,也只需在要處理的命令前加上 setsid 即可。

[code][root@pvcent107 ~]# setsid ping www.ibm.com > /dev/null 2>&1 &
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root     31094     1  0 07:28 ?        00:00:00 ping www.ibm.com
root     31102 29217  0 07:29 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#
值得注意的是,上例中我們的進程 ID(PID)為31094,而它的父 ID(PPID)為1(即為 init 進程 ID),並不是當前終端的進程 ID。請將此例與nohup 例中的父 ID 做比較。

&

這裡還有一個關於 subshell 的小技巧。我們知道,將一個或多個命名包含在“()”中就能讓這些命令在子 shell 中運行中,從而擴展出很多有趣的功能,我們現在要討論的就是其中之一。當我們將”&”也放入“()”內之後,我們就會發現所提交的作業並不在作業列表中,也就是說,是無法通過jobs來查看的。讓我們來看看為什麼這樣就能躲過 HUP 信號的影響吧。

subshell 示例

[code][root@pvcent107 ~]# (ping www.ibm.com &)
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root     16270     1  0 14:13 pts/4    00:00:00 ping www.ibm.com
root     16278 15362  0 14:13 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#

從上例中可以看出,新提交的進程的父 ID(PPID)為1(init 進程的 PID),並不是當前終端的進程 ID。因此並不屬於當前終端的子進程,從而也就不會受到當前終端的 HUP 信號的影響了

將當前進程改為脫機運行進程

disown

場景: 我們已經知道,如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 信號的影響。但是如果我們未加任何處理就已經提交了命令,該如何補救才能讓它避免 HUP 信號的影響呢?

解決方法: 這時想加 nohup 或者 setsid 已經為時已晚,只能通過作業調度和 disown 來解決這個問題了。讓我們來看一下 disown 的幫助信息

[code]disown [-ar] [-h] [jobspec ...]
    Without options, each jobspec is  removed  from  the  table  of
    active  jobs.   If  the -h option is given, each jobspec is not
    removed from the table, but is marked so  that  SIGHUP  is  not
    sent  to the job if the shell receives a SIGHUP.  If no jobspec
    is present, and neither the -a nor the -r option  is  supplied,
    the  current  job  is  used.  If no jobspec is supplied, the -a
    option means to remove or mark all jobs; the -r option  without
    a  jobspec  argument  restricts operation to running jobs.  The
    return value is 0 unless a jobspec does  not  specify  a  valid
    job.
可以看出,我們可以用如下方式來達成我們的目的。

用disown -h jobspec來使某個作業忽略HUP信號。

用disown -ah 來使所有的作業都忽略HUP信號。

用disown -rh 來使正在運行的作業忽略HUP信號。

ctrl-z 的用途就是將當前進程掛起(Suspend),然後我們就可以用jobs命令來查詢它的作業號,再用bg jobspec來將它放入後台並繼續運行。需要注意的是,如果掛起會影響當前進程的運行結果,請慎用此方法。

disown 示例1(如果提交命令時已經用“&”將命令放入後台運行,則可以直接使用“disown”)

[code][root@pvcent107 build]# cp -r testLargeFile largeFile &
[1] 4825
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile
root      4825   968  1 09:46 pts/4    00:00:00 cp -i -r testLargeFile largeFile
root      4853   968  0 09:46 pts/4    00:00:00 grep largeFile
[root@pvcent107 build]# logout

disown 示例2(如果提交命令時未使用“&”將命令放入後台運行,可使用 CTRL-z 和“bg”將其放入後台,再使用“disown”)

[code][root@pvcent107 build]# cp -r testLargeFile largeFile2

[1]+  Stopped                 cp -i -r testLargeFile largeFile2
[root@pvcent107 build]# bg %1
[1]+ cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile2
root      5790  5577  1 10:04 pts/3    00:00:00 cp -i -r testLargeFile largeFile2
root      5824  5577  0 10:05 pts/3    00:00:00 grep largeFile2
[root@pvcent107 build]#

screen

場景: 我們已經知道了如何讓進程免受 HUP 信號的影響,但是如果有大量這種命令需要在穩定的後台裡運行,如何避免對每條命令都做這樣的操作呢?

解決方法:此時最方便的方法就是 screen 了。簡單的說,screen 提供了 ANSI/VT100 的終端模擬器,使它能夠在一個真實終端下運行多個全屏的偽終端。screen 的參數很多,具有很強大的功能,我們在此僅介紹其常用功能以及簡要分析一下為什麼使用 screen 能夠避免 HUP 信號的影響。我們先看一下 screen 的幫助信息:

[code]SCREEN(1)                                                           SCREEN(1)

NAME
       screen - screen manager with VT100/ANSI terminal emulation

SYNOPSIS
       screen [ -options ] [ cmd [ args ] ]
       screen -r [[pid.]tty[.host]]
       screen -r sessionowner/[[pid.]tty[.host]]

DESCRIPTION
       Screen  is  a  full-screen  window manager that multiplexes a physical
       terminal between several  processes  (typically  interactive  shells).
       Each  virtual  terminal provides the functions of a DEC VT100 terminal
       and, in addition, several control functions from the  ISO  6429  (ECMA
       48,  ANSI  X3.64)  and ISO 2022 standards (e.g. insert/delete line and
       support for multiple character sets).  There is a  scrollback  history
       buffer  for  each virtual terminal and a copy-and-paste mechanism that
       allows moving text regions between windows.
使用 screen 很方便,有以下幾個常用選項:

用screen -dmS session name來建立一個處於斷開模式下的會話(並指定其會話名)。

用screen -list 來列出所有會話。

用screen -r session name來重新連接指定會話。

screen 示例

[code][root@pvcent107 ~]# screen -dmS Urumchi
[root@pvcent107 ~]# screen -list
There is a screen on:
        12842.Urumchi   (Detached)
1 Socket in /tmp/screens/S-root.

[root@pvcent107 ~]# screen -r Urumchi

當我們用“-r”連接到 screen 會話後,我們就可以在這個偽終端裡面為所欲為,再也不用擔心 HUP 信號會對我們的進程造成影響,也不用給每個命令前都加上“nohup”或者“setsid”了。這是為什麼呢?讓我來看一下下面兩個例子吧。

1. 未使用 screen 時新進程的進程樹

[code][root@pvcent107 ~]# ping www.google.com &
[1] 9499
[root@pvcent107 ~]# pstree -H 9499
init─┬─Xvnc
     ├─acpid
     ├─atd
     ├─2*[sendmail] 
     ├─sshd─┬─sshd───bash───pstree
     │       └─sshd───bash───ping

2. 使用了 screen 後新進程的進程樹

[code][root@pvcent107 ~]# screen -r Urumchi
[root@pvcent107 ~]# ping www.ibm.com &
[1] 9488
[root@pvcent107 ~]# pstree -H 9488
init─┬─Xvnc
     ├─acpid
     ├─atd
     ├─screen───bash───ping
     ├─2*[sendmail]

而使用了 screen 後就不同了,此時 bash 是 screen 的子進程,而 screen 是 init(PID為1)的子進程。那麼當 ssh 斷開連接時,HUP 信號自然不會影響到 screen 下面的子進程了。

總結

現在幾種方法已經介紹完畢,我們可以根據不同的場景來選擇不同的方案。nohup/setsid 無疑是臨時需要時最方便的方法,disown 能幫助我們來事後補救當前已經在運行了的作業,而 screen 則是在大批量操作時不二的選擇了。

進程管理

PS:查看某個時間點的進程

查看自己操作環境(bash)的相關進程

[code]
[root@pvcent107 ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 30581 30579  4  80   0 - 35931 sigsus pts/0    00:00:00 zsh
0 R     0 30620 30581  0  80   0 - 30319 -      pts/0    00:00:00 ps

//具體的詳細參數F,S,UID,PID.....請自行google,或參考鳥哥私房菜基礎篇第三版P516.

[root@pvcent107 ~]# ps -lA  <==大寫的A,顯示系統所有進程。與ps aux一樣,但顯示的條目標題不同
查看所有系統運行的進程

[code]
[root@pvcent107 ~]# ps aux          <==注意這裡沒有-

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  54340  4132 ?        Ss   5月22   0:11 /usr/lib/systemd/systemd --switched-root --system --deserialize 23
root         2  0.0  0.0      0     0 ?        S    5月22   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    5月22   0:00 [ksoftirqd/0]

....

//具體參數參考P517頁。
找出與crom與syslog服務有關的PID

[code][root@pvcent107 ~]# ps aux|egrep '(cron|syslog)'

僵屍進程

成因:通常,造成僵屍進程的成因是因為該進程應該已經執行完畢,或者是因故應該要終止了,但是該進程的父進程卻無法完整將該進程結束掉,而造成那個進程一直存在內存當中。

查看:當執行ps查看進程時,若進程後面有 < defunct>,就代表該進程時僵屍進程。比如:

[code]root     29570  4486  0 16:39 ?        00:00:00 [python] <defunct>

top:動態查看進程的變化

顯示內容解析

[code][root@TG1704 log]# top

top - 14:06:23 up 70 days, 16:44,  2 users,  load average: 1.25, 1.32, 1.35

Tasks: 206 total,   1 running, 205 sleeping,   0 stopped,   0 zombie

Cpu(s):  5.9%us,  3.4%sy,  0.0%ni, 90.4%id,  0.0%wa,  0.0%hi,  0.2%si,  0.0%st

Mem:  32949016k total, 14411180k used, 18537836k free,   169884k buffers

Swap: 32764556k total,        0k used, 32764556k free,  3612636k cached
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                
28894 root      22   0 1501m 405m  10m S 52.2  1.3   2534:16 java                                                                   
18249 root      18   0 3201m 1.9g  11m S 35.9  6.0 569:39.41 java

統計信息區:前五行是當前系統情況整體的統計信息區。下面我們看每一行信息的具體意義。

第一行,任務隊列信息,同 uptime 命令的執行結果,具體參數說明情況如下:14:06:23 — 當前系統時間

up 70 days, 16:44 — 系統已經運行了70天16小時44分鐘(在這期間系統沒有重啟過的吆!)

2 users — 當前有2個用戶登錄系統

load average: 1.15, 1.42, 1.44 — load average後面的三個數分別是1分鐘、5分鐘、15分鐘的負載情況。

load average數據是每隔5秒鐘檢查一次活躍的進程數,然後按特定算法計算出的數值。如果這個數除以邏輯CPU的數量,結果高於5的時候就表明系統在超負荷運轉了。

第二行, Tasks — 任務(進程),具體信息說明如下: 系統現在共有206個進程,其中處於運行中的有1個,205個在休眠(sleep),stoped狀態的有0個,zombie狀態(僵屍)的有0個。

第三行,cpu狀態信息,具體屬性說明如下:5.9%us — 用戶空間占用CPU的百分比。

3.4% sy — 內核空間占用CPU的百分比。

0.0% ni — 改變過優先級的進程占用CPU的百分比

90.4% id — 空閒CPU百分比

0.0% wa — IO等待占用CPU的百分比

0.0% hi — 硬中斷(Hardware IRQ)占用CPU的百分比

0.2% si — 軟中斷(Software Interrupts)占用CPU的百分比

備注:在這裡CPU的使用比率和windows概念不同,需要理解linux系統用戶空間和內核空間的相關知識!

第四行,內存狀態,具體信息如下: 32949016k total — 物理內存總量(32GB)

14411180k used — 使用中的內存總量(14GB)

18537836k free — 空閒內存總量(18GB)

169884k buffers — 緩存的內存量 (169M)

第五行,swap交換分區信息,具體信息說明如下:32764556k total — 交換區總量(32GB)

0k used — 使用的交換區總量(0K)

32764556k free — 空閒交換區總量(32GB)

3612636k cached — 緩沖的交換區總量(3.6GB)

將top信息進行2次,輸出到文本

[code][root@TG1704 log]# top -b -n 2 > /temp/top.txt

/*
 -d :  進程界面更新的秒數,默認是5秒
 -b :  以批次的方式執行top
 —n :  與-b搭配,意義是,需要進行幾次top的輸出結果。
 -p :  指定某個PID來進行檢測

交互命令

[code] ?: 顯示在top中可以輸入的按鍵命令
 P: 以CPU的使用資源排序顯示
 M: 以內存的使用資源排序顯示
 N: 以PID來排序
 T: 由該進程使用的cpu時間累積排序
 k: 給予某個PID一個信號
 r: 給予某個重新指定一個nice值
 q: 離開top
1.多U多核CPU監控

在top基本視圖中,按鍵盤數字“1”,可監控每個邏輯CPU的狀況:

2.進程字段排序輸入M(大寫),按內存占用率排序

輸入P(大寫),按cpu利用率排序

x(小寫):高亮排序的字段。

3,q,退出top

pstree,查看進程樹

進程優先級

[code][root@TG1704 log]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 30581 30579  0  80   0 - 35931 sigsus pts/0    00:00:00 zsh
0 R     0 32362 30581  0  80   0 - 30319 -      pts/0    00:00:00 ps

PRI表示進程優先級,PRI值越低代表優先級越大,PRI由內核動態調整的,用戶無法直接調整PRI。但可以設置Nice值PRI(new) = PRI(old)+nice

nice值的范圍是-20~19

所以當nice為負值時,該程序就會降低PRI值。

使用

[code]//在命令前加nice
[root@TG1704 log]# nice -n -5 vim temp.txt & 

[root@TG1704 log]# renice [number] PID

系統資源的查看

free:查看內存使用情況uname -a:查看系統內核信息

uptime:查看系統啟動時間與工作負載netstat:跟蹤網絡

dmesg:輸出所有的內核開機信息vmstat:檢測系統資源變化

Copyright © Linux教程網 All Rights Reserved