Shell與進程


查看當前運行的進程

名稱:       ps
使用權限:    所有使用者
使用方式:    ps [options] [--help]
說明:       顯示瞬間行程 (process) 的動態
參數:       ps的參數非常多, 在此僅列出幾個常用的參數並大略介紹含義

 

常用參數

-A    顯示所有進程(等價於-e)(utility)
-a    顯示一個終端的所有進程,除了會話引線
-N    忽略選擇。
-d    顯示所有進程,但省略所有的會話引線(utility)
-x    顯示沒有控制終端的進程,同時顯示各個命令的具體路徑。dx不可合用。(utility)
-p    pid 進程使用cpu的時間
-u    uid or username 選擇有效的用戶id或者是用戶名
-g    gid or groupname 顯示組的所有進程。
-m    顯示所有的線程
-f    全部列出,通常和其他選項聯用。如:ps -fa or ps -fx and so on.
-l    長格式(有F,wchan,C 等字段)
-j    作業格式
-o    用戶自定義格式。
-w    顯示加寬可以顯示較多的資訊
-H    顯示進程的層次(和其它的命令合用,如:ps -Ha)(utility)
v     以虛擬存儲器格式顯示
s     以信號格式顯示
U     username 顯示該用戶下的所有進程,且顯示各個命令的詳細路徑。如:ps U zhang;(utility)
e     命令之后顯示環境(如:ps -d e; ps -a e)(utility)
h     不顯示第一行

 

常用組合

ps a    顯示現行終端機下的所有程序,包括其他用戶的程序。
ps -A   顯示所有進程。
ps c    列出程序時,顯示每個程序真正的指令名稱,而不包含路徑,參數或常駐服務的標示。
ps -e   此參數的效果和指定"A"參數相同。
ps e    列出程序時,顯示每個程序所使用的環境變量。
ps f    用ASCII字符顯示樹狀結構,表達程序間的相互關系。
ps -H   顯示樹狀結構,表示程序間的相互關系。
ps -N   顯示所有的程序,除了執行ps指令終端機下的程序之外。
ps s    采用程序信號的格式顯示程序狀況。
ps S    列出程序時,包括已中斷的子程序資料。
ps -t<終端機編號>  指定終端機編號,並列出屬於該終端機的程序的狀況。
ps u    以用戶為主的格式來顯示程序狀況。
ps x    顯示所有程序,不以終端機來區分。
最常用的方法是ps -aux,然后再利用一個管道符號導向到grep去查找特定的進程,然后再對特定的進程進行操作。

 

head標頭

USER    用戶名
UID     用戶ID(User ID)
PID     進程ID(Process ID)
PPID    父進程的進程ID(Parent Process id)
SID     會話ID(Session id%CPU    進程的cpu占用率
%MEM    進程的內存占用率
VSZ     進程所使用的虛存的大小(Virtual Size)
RSS     進程使用的駐留集大小或者是實際內存的大小,Kbytes字節。
TTY     與進程關聯的終端(tty)
STAT    進程的狀態:進程狀態使用字符表示的(STAT的狀態碼)
    R    運行,Runnable (on run queue);正在運行或在運行隊列中等待。
    S    睡眠,Sleeping;休眠中, 受阻, 在等待某個條件的形成或接受到信號。
    I    空閑,Idle
    Z    僵死,Zombie(a defunct process);進程已終止, 但進程描述符存在, 直到父進程調用wait4()系統調用后釋放。
    D    不可中斷,Uninterruptible sleep (ususally IO);收到信號不喚醒和不可運行, 進程必須等待直到有中斷發生。
    T    終止,Terminate;進程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信號后停止運行運行。
    P    等待交換頁
    W    無駐留頁,has no resident pages;沒有足夠的記憶體分頁可分配。
    X    死掉的進程
    <    高優先級進程
    N    低優先級進程
    L    內存鎖頁,Lock;有記憶體分頁分配並縮在記憶體內
    s    進程的領導者(在它之下有子進程);
    l    多進程的(使用 CLONE_THREAD, 類似 NPTL pthreads)
    +    位於后台的進程組
STIME    進程啟動時間和日期
TIME     進程使用的總cpu時間
COMMAND  正在執行的命令行命令
NI       優先級(Nice)
PRI      進程優先級編號(Priority)
WCHAN    進程正在睡眠的內核函數名稱;該函數的名稱是從/root/system.map文件中獲得的。
FLAGS    與進程相關的數字標識

 

創建進程

准備知識

  • 我們所執行的任何程序,都是由父進程(parent process)所產生出來的一個子進程(child process),子進程在結束后,將返回到父進程去。此一現像在Linux系統中被稱為 fork。當子進程被產生的時候,將會從父進程那里獲得一定的資源分配、及(更重要的是)繼承父進程的環境﹗
  • Shell變量大致可以分為3種類型:
  1. 內部變量:系統提供,不用定義,不能修改,比如$#,$?,$*,$0等
  2. 環境變量:系統提供,不用定義,可以修改,當前進程及其子進程中使用,比如PATH,PWD,SHELL等
  3. 用戶變量(本地變量):用戶定義,可以修改,在當前進程使用,比如var=123等
  4. 與其他語言的區別:非類型性質,也就是不必指定變量是數字或字符串等。
  • 關於環境變量:環境變量只能從父進程到子進程單向繼承。換句話說:在子進程中的環境如何變更,均不會影響父進程的環境。
  • Shell腳本:其實就是將你平時在Shell prompt后所輸入的多行command依序寫入一個文件去而已

 

fork,source和exec方式執行Shell腳本 

fork方式 

也就是常用的方式,一般在shell直接輸入腳本文件路徑就可以了。這種方式由當前進程創建一個子進程,如下:

./mytest.sh

或者

bash
mytest.sh

 

source方式

使用方式如下(source與".”等價):

source ./mytest.sh
或者
. ./mytest.sh
source方式的特點是,在不另外創建子進程,而是在當前的的Shell環境中執行。

 

exec方式
exec ./mytest.sh
此方式的特點是,不另外創建子進程,但是會終止當前的shell執行(其實我覺得這樣理解可能更准確:使用exec會在當前的進程空間創建一個子線程,然后終止當前線程的執行,到了新建的線程執行完之后,其實兩個線程都終止了,也就是這個當前shell進程也就終止了) 

 

測試一 

創建test1.sh,內容如下:

#!/bin/sh
cd~/bin
pwd
分別使用三種方式執行,source與exec方式都會將目錄更改應用到當前環境,不同的是,exec方式執行完之后,shell環境就不能夠使用了,會自動重啟一個新的shell環境(進程)

 

測試二 

一個更為詳實的測試,腳本

腳本1.sh
#!/bin/sh
A=B
echo"PID for 1.sh before exec/source/fork:$$"
export A
echo"1.sh: /$A is $A"
case $1 in
exec)
echo "using exec..."
exec. /2.sh;;
source)
echo "using source..."
. ./2.sh;;
*)
echo "using fork by default..."
./2.sh;;
esac
echo "PID for 1.sh after exec/source/fork:$$"
echo "1.sh: /$A is $A"

腳本2.sh
#!/bin/sh
echo "PID for 2.sh: $$"
echo "2.sh get /$A=$A from 1.sh"
A=C
export A
echo "2.sh: /$A is $A"

 

分別使用三種方式執行1.sh腳本,結果如下:

~$./1.sh fork

PID for 1.sh before exec/source/fork:531
1.sh: $A is B
using fork by default...
PID for 2.sh:532
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:531
1.sh: $A is B
~$ ./1.sh source

PID for 1.sh before exec/source/fork:533
1.sh: $A is B
using source...
PID for 2.sh:533
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:533
1.sh: $A is C
~$ ./1.sh exec

PID for 1.sh before exec/source/fork:537
1.sh: $A is B
using exec...
PID for 2.sh:537
2.sh get $A=B from 1.sh
2.sh: $A is C

注意:使用exec執行時1.sh中最后兩句並沒有被執行

 

終止進程之kill命令

  Linux中的kill命令用來終止指定的進程(terminate a process)的運行,是Linux下進程管理的常用命令。通常,終止一個前台進程可以使用Ctrl+C鍵,但是,對於一個后台進程就須用kill命令來終止,我們就需要先使用ps/pidof/pstree/top等工具獲取進程PID,然后使用kill命令來殺掉該進程。kill命令是通過向進程發送指定的信號來結束相應進程的。在默認情況下,采用編號為15的TERM信號。TERM信號將終止所有不能捕獲該信號的進程。對於那些可以捕獲該信號的進程就要用編號為9的kill信號,強行“殺掉”該進程。

 

命令格式

kill [參數] [進程號]

 

命令功能

  發送指定的信號到相應進程。不指定型號將發送SIGTERM(15)終止指定進程。如果任無法終止該程序可用“-KILL” 參數,其發送的信號為SIGKILL(9) ,將強制結束進程,使用ps命令或者jobs 命令可以查看進程號。root用戶將影響用戶的進程,非root用戶只能影響自己的進程。

 

命令參數

-l  信號,若果不加信號的編號參數,則使用“-l”參數會列出全部的信號名稱
-a  當處理當前進程時,不限制命令名和進程號的對應關系
-p  指定kill 命令只打印相關進程的進程號,而不發送任何信號
-s  指定發送信號
-u  指定用戶

注意:

  • kill命令可以帶信號號碼選項,也可以不帶。如果沒有信號號碼,kill命令就會發出終止信號(15),這個信號可以被進程捕獲,使得進程在退出之前可以清理並釋放資源。也可以用kill向進程發送特定的信號。例如:kill -2 123,它的效果等同於在前台運行PID為123的進程時按下Ctrl+C鍵。但是,普通用戶只能使用不帶signal參數的kill命令或最多使用-9信號。
  • kill可以帶有進程ID號作為參數。當用kill向這些進程發送信號時,必須是這些進程的主人。如果試圖撤銷一個沒有權限撤銷的進程或撤銷一個不存在的進程,就會得到一個錯誤信息。
  • 可以向多個進程發信號或終止它們。
  • 當kill成功地發送了信號后,shell會在屏幕上顯示出進程的終止信息。有時這個信息不會馬上顯示,只有當按下Enter鍵使shell的命令提示符再次出現時,才會顯示出來。
  • 應注意,信號使進程強行終止,這常會帶來一些副作用,如數據丟失或者終端無法恢復到正常狀態。發送信號時必須小心,只有在萬不得已時,才用kill信號(9),因為進程不能首先捕獲它。要撤銷所有的后台作業,可以輸入kill 0。因為有些在后台運行的命令會啟動多個進程,跟蹤並找到所有要殺掉的進程的PID是件很麻煩的事。這時,使用kill 0來終止所有由當前shell啟動的進程,是個有效的方法。

 

示例

實例1:列出所有信號名稱

[root@localhost test6]# 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

說明:
只有第9種信號(SIGKILL)才可以無條件終止進程,其他信號進程都有權利忽略。    下面是常用的信號:
HUP     1    終端斷線
INT     2    中斷(同 Ctrl + C)
QUIT    3    退出(同 Ctrl + \)
TERM    15   終止
KIL     9    強制終止
CONT    18   繼續(與STOP相反, fg/bg命令)
STOP    19   暫停(同 Ctrl + Z)

 

實例2:得到指定信號的數值

[root@localhost test6]# kill -l KILL
9
[root@localhost test6]# kill -l SIGKILL
9
[root@localhost test6]# kill -l TERM
15
[root@localhost test6]# kill -l SIGTERM
15

 

實例3:殺死指定用戶所有進程

[root@localhost ~]# kill -9 $(ps -ef | grep peidalinux) 
[root@localhost ~]# kill -u peidalinux

 

注意:init是Linux系統操作中不可缺少的程序之一。所謂的init進程,它是一個由內核啟動的用戶級進程。內核自行啟動(已經被載入內存,開始運行,並已初始化所有的設備驅動程序和數據結構等)之后,就通過啟動一個用戶級程序init的方式,完成引導進程。所以,init始終是第一個進程(其進程編號始終為1)。 其它所有進程都是init進程的子孫。init進程是不可殺的!

 

參考文檔https://www.linux.org/threads/kill-signals-and-commands-revised.11625/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM