2012/08/26

Linux Process


什麼是Process

  • 程序是一段指令的集合,被載入記憶體
  1. 使用 Numeric Process ID (PID) 識別程序
  2. UID, GID and SELinux context 決定 filesystem 存取
    1. Normally 繼承 from the 執行者

列出 Process

  • View Process information with ps
[lcc09@localhost ~]$ ps --help
********* simple selection *********  ********* selection by list *********
-A 所有的程序                         -C by command name
-N negate selection                   -G by real group ID (supports names)
-a all w/ tty except session leaders  -U by real user ID (supports names)
-d all except session leaders         -g by session OR by effective group name
-e all processes                      -p by process ID
T  all processes on this terminal     -s processes in the sessions given
a  all w/ tty, including other users  -t by tty
g  OBSOLETE -- DO NOT USE             -u by effective user ID (supports names)
r  only running processes             U  processes for specified users
x  把包含不被ttys控制的程序都列出來
*********** output format **********  *********** long options ***********
-o,o user-defined  -f full            --Group --User --pid --cols --ppid
-j,j job control   s  signal          --group --user --sid --rows --info
-O,O preloaded -o  v  virtual memory  --cumulative --format --deselect
-l,l long          u  user-oriented   --sort --tty --forest --version
-F   extra full    X  registers       --heading --no-heading --context
                    ********* misc options *********
-V,V  show version      L  list format codes  f  ASCII art forest
-m,m,-L,-T,H  threads   S  children in sum    -y change -l format
-M,Z  security data     c  true command name  -c scheduling class
-w,w  wide output       n  numeric WCHAN,UID  -H process hierarchy
  • 常用的ps指令
[lcc09@localhost ~]$ ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:02 init [5]
    2 ?        S      0:00 [migration/0]
    3 ?        SN     0:00 [ksoftirqd/0]
    4 ?        S      0:00 [watchdog/0]
    5 ?        S<     0:00 [events/0]
    6 ?        S<     0:00 [khelper]
    7 ?        S<     0:00 [kthread]
   10 ?        S<     0:00 [kblockd/0]
   11 ?        S<     0:00 [kacpid]
   67 ?        S<     0:00 [cqueue/0]
   70 ?        S<     0:00 [khubd]
   72 ?        S<     0:00 [kseriod]
  134 ?        S      0:00 [pdflush]
  135 ?        S      0:01 [pdflush]
  136 ?        S<     0:01 [kswapd0]
  137 ?        S<     0:00 [aio/0]
  289 ?        S<     0:00 [kpsmoused]
  320 ?        S<     0:00 [scsi_eh_0]
  325 ?        S<     0:00 [kmirrord]
  330 ?        S<     0:00 [ksnapd]
  333 ?        S<     0:03 [kjournald]
  366 ?        S<     0:00 [kauditd]
...(略)...
  • Most flexible: ps options | other commands
ps axo comm,tty | grep ttyS0
  • By 預先定義選項的: pgrep
  1. $ pgrep -U root
  2. $ pgrep -G student
  • 練習
[lcc09@localhost ~]$ ps axo pid,comm  | grep 'cups'
 1948 cupsd
 2464 eggcups
[lcc09@localhost ~]$ pgrep cups
1948
2464

信號

  • 信號是程序之間用來溝通的基礎方式
  1. Sent directly to processes, no user-interface required
  2. 程式會結合並注意著每個信號
  3. 有幾個較為特別的 Signals
    1. Signal 15, TERM (default) - 乾淨的終止程序
    2. Signal 9, KILL - 立即終止程序
    3. Signal 1, HUP - Re-read configuration files
  • man 7 signal 可以得到完整的信號列表

送出信號給程序

  • 送出 Signals to Processes
  1. 語法 By PID: kill [signal] pid ...
  2. 語法 By Name: killall [signal] comm ...
  3. 語法 By pattern: pkill [-signal] pattern

排成優先等級

  • 排成的優先等級決定存取 CPU 的順序
  • 排成決定在 process' nice 值
  • 值的範圍從 -20 到 19 預設為 0
  1. 越低的值,有越高的的優先權
  • 可以使用這些指令觀看 ps -o comm,nice

修改優先等級

  • 修改排成優先等級
  • Process's Nice values 可以被改變
  1. 當啟動一個 process
  $ nice -n 5 command
  1. 啟動之後可以這樣修改
  $ renice 5 PID
  • 只有 root 能增減 nice values
[root@localhost ~]# renice -15 -p PID
# PID is number

Interactive Process Management Tools

  • CLI: top
  • GUI: gnome-system-monitor
  • Capabilities
  1. Display real-time process information
  2. Allow sorting, killing and re-nicing

工作任務控制

  • Job Control
  • 執行一個程序在背景工作
  1. 只要在指令後面加上一個「&」符號
  2. ex: gedit &
  • 暫時停止一個執行中的程式
  1. Use Ctrl + Z or 或送出 signal 19 (STOP)
  • 管理 背景程序 or 暫停程序 的 jobs
  1. 列出工作編號及名稱指令: jobs
  2. 轉移工作到背景繼續工作: bg [%jobnum]
  3. 轉移工作到前景繼續工作: fg [%jobnum]
  4. Send a signal: kill [-SIGNAL] [%jobnum]
  • 範例:
[mtchang@localhost ~]$  top
# 按下ctrl+z
[1]+  Stopped                 top
[mtchang@localhost ~]$  ps
  PID TTY          TIME CMD
 3590 pts/2    00:00:00 bash
 3961 pts/2    00:00:00 top
 3962 pts/2    00:00:00 ps
[mtchang@localhost ~]$  ping 168.95.1.1
PING 168.95.1.1 (168.95.1.1) 56(84) bytes of data.
64 bytes from 168.95.1.1: icmp_seq=1 ttl=244 time=25.2 ms
# 按下ctrl+z
[2]+  Stopped                 ping 168.95.1.1
[mtchang@localhost ~]$  jobs
[1]-  Stopped                 top
[2]+  Stopped                 ping 168.95.1.1
[mtchang@localhost ~]$  fg 2
# 叫出第二個工作
ping 168.95.1.1
64 bytes from 168.95.1.1: icmp_seq=2 ttl=244 time=155 ms
64 bytes from 168.95.1.1: icmp_seq=3 ttl=244 time=42.3 ms
64 bytes from 168.95.1.1: icmp_seq=4 ttl=244 time=63.9 ms
64 bytes from 168.95.1.1: icmp_seq=5 ttl=244 time=54.1 ms

--- 168.95.1.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 35174ms
rtt min/avg/max/mdev = 25.232/68.245/155.555/45.519 ms, pipe 2
[mtchang@localhost ~]$  jobs
[1]+  Stopped                 top
[mtchang@localhost ~]$  fg 
# 叫出順序中的第一個工作

nohup

  • 讓程序不會因為父程序消失而結束,程序可以成為一個獨立的程序系統中工作。
  • Usage: nohup COMMAND [ARG]... or: nohup OPTION
  • Run COMMAND, ignoring hangup signals.
  • 一般的wget作法,關掉視窗後,程式下載即消失。
$  wget ftp://ftp.isu.edu.tw/Linux/CentOS/5.0/isos-dvd/
CentOS-5.0-i386-bin-DVD.iso 2>wget.err >wget.doc &
$ jobs
[1]+  Running wget ftp://ftp.isu.edu.tw/Linux/CentOS/5.0/isos-dvd/
CentOS-5.0-i386-bin-DVD.iso 2>wget.err >wget.doc &
*使用nohup
$ nohup wget ftp://ftp.isu.edu.tw/Linux/CentOS/5.0/isos-dvd/
CentOS-5.0-i386-bin-DVD.iso 2>wget.err >wget.doc &
[2] 4096
$ ps auxw
lcc09     4096  1.0  0.2   7884  1416 pts/1    S    20:50   0:00
 wget ftp://ftp.isu.edu.tw/Linux/CentOS/5.0/isos-dvd/CentOS-5.0-i386 
$ kill 4096
[lcc09@localhost:~bash: echo: write error: 中斷的系統呼叫
[2]+  終止                  
nohup wget ftp://ftp.isu.edu.tw/Linux/CentOS/5.0/isos-dvd/
CentOS-5.0-i386-bin-DVD.iso 2>wget.err >wget.doc
  • kill 傳送訊號範例
# 另開一個終端機畫面執行 top 指令
[root@server1 ~]# ps auxw
...
root      4482  0.1  0.0   2188  1064 pts/10   S+   19:38   0:00 top
...
# 送訊號 19 給 4482 PID 的程序,以中斷信號
[root@server1 ~]# kill -19 4482
# 回到終端機畫面驗證

# 程式內容如下
[student@localhost sh]$ cat num.sh 
#!/bin/bash
for n in {1..4}; 
do
        echo 192.168.3.$n
        echo "ping 192.168.3.$n -c1 1> /dev/null 2> /dev/null " | bash
        echo "return value =  $?"
done 

# 程式可以執行,但是偵測速度很慢
[student@localhost sh]$ ./num.sh 
192.168.3.1
return value =  0
192.168.3.2
return value =  1
192.168.3.3
return value =  1
192.168.3.4
return value =  1

排定程序執行

  • 一次性的工作使用「at」
  • 重複性的工作使用「crontab 」
Create(建立指令)at timecrontab -e
List(列出)at -lcrontab -l
Details(詳細)at -c jobnumN/A
Remove(移除)at -d jobnumcrontab -r
EditN/Acrontab -e
  • Non-redirected output is mailed to the user
  • root can modify jobs for other users
  • man at
NAME
       at,  batch,  atq,  atrm - queue, examine or delete jobs for
       later execution

SYNOPSIS
       at [-V] [-q queue] [-f file] [-mldbv] TIME
       at [-V] [-q queue] [-f file] [-mldbv] -t time_arg
       at -c job [job...]
       atq [-V] [-q queue]
       atrm [-V] job [job...]
       batch [-V] [-q queue] [-f file] [-mv] [TIME]

  • at範例
[mtchang@localhost ~]$ date
一  6月  4 23:32:01 CST 2007
[mtchang@localhost ~]$ at 23:34 
at> echo 'test at ' > at.txt
at> 
# Ctrl-d end of line
job 1 at 2007-06-04 23:34
[mtchang@localhost ~]$ at -l
# list at jobs
1       2007-06-05 23:34 a mtchang
[mtchang@localhost ~]$ date
一  6月  4 23:34:17 CST 2007
[mtchang@localhost ~]$ more at.txt 
test at 

Crontab(定時排程)

  • 系統的工作控制都排程在這個目錄 /etc/crontab
  1. /etc/cron.hourly/ Jobs are run on an hourly basis
  2. /etc/cron.daily/ Jobs are run on a daily basis
  3. /etc/cron.weekly/ Jobs are run on a weekly basis
  4. /etc/cron.monthly/ Jobs are run on a monthly basis
  • 排程的工作可以針對單獨的使用者排定,這些工作儲存於 /var/spool/crontab
  • 你可以使用crontab指令來編輯這些資料,指令用法如下:
  1. crontab -e Creates or edits jobs. For this, the vi editor is used.
  2. crontab file The specified file contains a list of jobs.
  3. crontab -l Displays current jobs.
  4. crontab -r Deletes all jobs.
  • ex: user crontab
[lcc09@localhost ~]$ crontab -e
30 * * * * echo 'hello crontab' > /home/lcc09/crontab.txt
[lcc09@localhost ~]$ cat crontab.txt 
hello crontab
  • ex: root crontab , in every day 21:45 shutdown computer
# 需注意halt路徑,且halt關機並不會把電源也關閉,請改用shutdown or poweroff指令
45 21 * * * root /usr/sbin/halt
  • Crontab檔案格式說明
  • Entry consists of five space-delimited fields followed by a command line
  1. One entry per line, no limit to line length
  • Fields are minute, hour, day of month, month, and day of week
  • Comment lines begin with #
  • See man 5 crontab for details
...(skip)....
              field          allowed values
              -----          --------------
              minute         0-59
              hour           0-23
              day of month   1-31
              month          1-12 (or names, see below)
              day of week    0-7 (0 or 7 is Sun, or use names)
...(skip)....
  • 常用的crontab 範例
EXAMPLE CRON FILE
# use /bin/sh to run commands, no matter what /etc/passwd says
SHELL=/bin/sh
# mail any output to ‘paul’, no matter whose crontab this is
MAILTO=paul
#
# run five minutes after midnight, every day
5 0 * * *       $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
# run at 2:15pm on the first of every month -- output mailed to paul
15 14 1 * *     $HOME/bin/monthly
# run at 10 pm on weekdays, annoy Joe
0 22 * * 1-5   mail -s "It’s 10pm" joe%Joe,%%Where are your kids?%
23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
5 4 * * sun     echo "run at 5 after 4 every sunday"

Grouping Commands

  • Two ways to group commands:
  1. Compound: date; who | wc -l
    1. Commands run back-to-back
  2. Subshell: (date; who | wc -l) >> /tmp/trace
    1. All output is sent to a single STDOUT and STDERR

Exit Status

  • 程序(Processes)回報完成程序後,會回報成功或失敗 with an exit status
  1. 0 是成功完成, 1-255 是失敗的錯誤訊息編號
  2. $? 儲存離開的狀態變數
  3. exit [num] terminates and sets status to num
  • Example:
[mtchang@localhost ~]$ ping -c1 -W1 168.91.1.1 > /dev/null
[mtchang@localhost ~]$ echo $?
1

Conditional Execution Operators

  • Commands can be run conditionally based on exit status
  1. && represents conditional AND THEN
  2. || represents conditional OR ELSE
  • 執行真值表,表列如下:
第一個指令執行連接符號第二指令執行狀態
成功||不執行
失敗||執行
成功&&執行
失敗&&不執行
  • Examples:
[mtchang@localhost ~]$ grep -q no_user /etc/passwd || echo 'No such user'
No such user
# the second command runs if the first command fails
# (it exits with an exit statis in th range of 1 ro 255)
[mtchang@localhost ~]$ grep -q lcc09 /etc/passwd || echo 'No such user'
[mtchang@localhost ~]$ grep -q lcc09 /etc/passwd && echo 'No such user'
No such user
  • ping 的範例
[student@localhost sh]$ \
echo "ping -c 3 192.168.3.1 >> ping_192.168.3.1.txt || echo 1 >\
 ping_192.168.3.1.txt &" | bash
[student@localhost sh]$ \
echo "ping -c 3 192.168.3.2 >> ping_192.168.3.2.txt || echo 1 >\
 ping_192.168.3.2.txt &" | bash
[student@localhost sh]$ tail ping_192.168.3.1.txt 
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.460/0.609/0.860/0.180 ms
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq=1 ttl=255 time=0.476 ms
64 bytes from 192.168.3.1: icmp_seq=2 ttl=255 time=0.466 ms
64 bytes from 192.168.3.1: icmp_seq=3 ttl=255 time=0.471 ms

--- 192.168.3.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.466/0.471/0.476/0.004 ms
[student@localhost sh]$ tail ping_192.168.3.2.txt 
1

test Command

  • Evaluates boolean statements for use in conditional execution
  1. Returns 0 for true
  2. Returns 1 or more for false
  • Examples in long form:
$ test "$A" = "$B" && echo "Strings are equal" $ test "$A" -eq "$B" && echo "Integers are equal"
  • Examples in shorthand notation:
$ [ "$A" = "$B" ] && echo "Strings are equal" $ [ "$A" -eq "$B" ] && echo "Integers are equal"
[mtchang@localhost ~]$ test "$A"  =  "$B" && echo "Strings are equal"
Strings are equal
[mtchang@localhost ~]$ A='aaa'
[mtchang@localhost ~]$ test "$A"  =  "$B" && echo "Strings are equal"
[mtchang@localhost ~]$ B='aaa'
[mtchang@localhost ~]$ test "$A"  =  "$B" && echo "Strings are equal"
Strings are equal
  • File Tests
  1. -b FILE FILE exists and is block special
  2. -c FILE FILE exists and is character special
  3. -d FILE FILE exists and is a directory
  4. -e FILE FILE exists
  5. -f FILE FILE exists and is a regular file
  6. -g FILE FILE exists and is set-group-ID
  7. -G FILE FILE exists and is owned by the effective group ID
  8. -h FILE FILE exists and is a symbolic link (same as -L)
  9. -k FILE FILE exists and has its sticky bit set
  10. -L FILE FILE exists and is a symbolic link (same as -h)
  11. -O FILE FILE exists and is owned by the effective user ID
  12. -p FILE FILE exists and is a named pipe
  13. -r FILE FILE exists and read permission is granted
  14. -s FILE FILE exists and has a size greater than zero
  15. -S FILE FILE exists and is a socket
  16. -t FD file descriptor FD is opened on a terminal
  17. -u FILE FILE exists and its set-user-ID bit is set
  18. -w FILE FILE exists and write permission is granted
  19. -x FILE FILE exists and execute (or search) permission is granted

Scripting: if Statements

  • Execute instructions based on the exit status of a command
  • 原始基本型的 if then fi
[lcc09@localhost ~]$ vi if.sh
#!/bin/bash
if ping -c1 -w2 168.95.1.1 &> /dev/null; then
    echo 'Station1 is UP'
fi
[lcc09@localhost ~]$ chmod +x if.sh
[lcc09@localhost ~]$ ./if.sh
Station1 is UP
  • 包含else if的敘述
[mtchang@localhost ~]$ vi if.sh
#!/bin/bash
if ping -c1 -w2 168.95.1.1 &> /dev/null; then
    echo 'Station1 is UP'
elif grep "station1" ~/maintenance.txt &> /dev/null; then
    echo 'Station1 is undergoing maintenance'
else
    echo 'Station1 is unexpectedly DOWN!'
    exit 1
fi
[mtchang@localhost ~]$ chmod +x if.sh 
[mtchang@localhost ~]$ ./if.sh 
Station1 is UP
  • 延續上面的 ping 範例
[student@localhost sh]$ cat testping.sh 
#!/bin/bash

if test $(tail -n 1 ping_192.168.3.1.txt|cut -d' ' -f1) = '1'; then 
        echo "192.168.3.1 is down"
      else
        echo "192.168.3.1 is up!!"
fi

[student@localhost sh]$ ./testping.sh 
192.168.3.1 is up!!

參考文件

張貼留言