13、进程 (shell脚本学习指南) 转
1、查看进程负载(uptime)
该命令显示开机至今的时间、用户数、及平均负载
当平均负载持续地超出可用cpu(cpu个数)的承载时,表示系统工作已超出它所能负荷了,此时响应可能会陷入停滞不前的状态
2、进程列表
(1)ps:显示进程状态,该命令与ls命令相似
(2)top:会在列表顶端显示cpu耗用最多的进程
(3)在shell中,进程ID可以用$$表示
(4)shell在处理下一个命令之前会等待一进程结束,不过只要在命令最后加入&字符,而非分号或换行符号,便能将进程放在后台中执行。wait命令可用以等待某个特定进程完成,在不加载任何参数的情况下,则为等待所有后台进程的完成
keyaming@ubuntu:~$ sleep 20 && echo himan & //在后台执行该命令:先睡眠20秒然后输出
[1] 3496
keyaming@ubuntu:~$ wait 3496 && echo h //等待3496进程执行完成之后输出
himan
[1]+ Done sleep 20 && echo himan
h
(5)有4组键盘字符可用以中断前台进程。这些字符都可通过stty命令选项设置,通常为Ctrl+C(intr:杀除)Ctrl+Y(dsusp:暂时搁置,直到输入更新为止)Ctrl+Z(susp:暂时搁置)Ctrl+\(quit:以核心转储(core dump)方式杀除)
3、进程控制与删除(kill)
(1)kill是传送信号给指定的执行中程序。
(2)kill -l :列出支持的信号名称
(3)删除进程的四个信号
ABRT(中断):快速的清除并离开,如果未指定信号,则kill会送出此信号
TERM(终结):类似于ABRT,不过它会抑制清除的操作,并产生进程内存影像的副本,将其置于核心,即program.core或core.PID
HUG(搁置):有点类似于终止,常用于重新启动
KILL:让进程立即终止
STOP与TSTP:通常只是暂停进程。
CONT:在使用STOP暂停进程后,利用这个可以恢复进程
注:KILL与STOP这两个信号没有任何进程可捕捉或忽略,他们一定会立即被传送。而大部分的其他信号都只在进程醒着的时候才传送。
按惯例而言,应该先送出HUP信号给进程,让进程有机会优雅的中止。如果它没有马上离开,再试试TERM信号。如果仍无法离开,在使用最后手段KILL信号。
例子:
$top 显示top的资源消耗情况
33663 chrome
$kill -STOP 33663 终止进程,则chrome浏览器无响应
$kill -CONT 33663 恢复,浏览器正常执行
(4)以名称追踪并删除进程
pgrep:显示进程编号
pkill:删除进程,如果未提供额外命令行选项,则pkill会传送一信号给所有指定名称的进程。
$pgrep chrome 寻找chrome工作的进程编号
33663
$pkill -HUP chrome 传送HUP信号给chrome进程
4、捕捉进程信号(trap)
(1)trap信号可引起shell注册信号处理器,抓取指定的信号。trap取得一个字符串参数,其包含采取捕捉时要被执行的命令列表,紧接着一个要设置捕捉的信号列表。
(3)特殊信号
EXIT:在做exit系统调用之前被引用,不适明确的exit命令,就是脚本的正常终止,如果为其他信号而设置捕捉,则这些捕捉会在EXIT捕捉之前被处理。
DEBUG:用以捕捉每个语句
ERR:捕捉在语句之后回传的非零值离开码
例子:捕捉EXIT信号和DEBUG信号
keyaming@ubuntu:~$ cat debug-trap
trap 'echo this an EXIT trap' EXIT
trap 'echo this an DEBUG trap' DEBUG
pwd
pwd
keyaming@ubuntu:~$ ./debug-trap
this an DEBUG trap
/home/keyaming
this an DEBUG trap
/home/keyaming
this an DEBUG trap
this an EXIT trap
例子:捕捉ERR信号
keyaming@ubuntu:~$ cat err-trap.sh
trap 'echo this is an ERR trap' ERR
ls no-such-file
keyaming@ubuntu:~$ ./err-trap.sh
ls: 无法访问no-such-file: 没有那个文件或目录
this is an ERR trap
5、进程系统调用的追踪
例子:
keyaming@ubuntu:~$ PS1='trace-sh$' strace -e trace=process /bin/sh
execve("/bin/sh", ["/bin/sh"], [/* 41 vars */]) = 0
wait4(-1, 0xbf9c2ba4, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
trace-sh$pwd
/home/keyaming
wait4(-1, 0xbf9c2ba4, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
trace-sh$/bin/pwd
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7702938) = 4553
wait4(-1, /home/keyaming
[{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED, NULL) = 4553
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, 0xbf9c2ba4, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
trace-sh$exit
exit_group(0) = ?
keyaming@ubuntu:~$
设置提示号变量PS1,以兹区别于原始与被追踪的shell,这么以来,便能在每一行评注上它的来源了。
6、延迟的进程调度
(1)所有的命令只要在最后加上&字符,都可起始于后台执行,无须等待。只有在少数情况下,必须等待后台进程完成
(2)延迟片刻:sleep
当进程应于某个特定时间过后才能启动时,可使用sleep命令暂停执行一段指定的秒数之后,再下达被延迟的命令。sleep使用的资源很少,且可在不会对活动中的进程有任何干扰下被使用。
(3)at:延迟至特定的时间
at命令可以令程序在特定的时间执行。但是任何出现在标准错误输出或标准输出上的数据都会寄给你,而不会显示在终端上。同时at也不会执行需要交互执行的程序,因为用户无法通过终端进行输入
atq列出at队列里的所有工作,而atrm(+任务号)则是删除他们。
例子:
keyaming@ubuntu:~$ at now + 1 minutes //在一分钟后执行
warning: commands will be executed using /bin/sh
at> ls > file
at> <EOT> //该符号表示Ctrl+D,表示结束输入任务
job 34 at Sun Aug 19 16:08:00 2012
keyaming@ubuntu:~$ atq //列出已添加的任务
例子:通过文件输入命令
keyaming@ubuntu:~$ cat command
ls > file
keyaming@ubuntu:~$ at now + 1 minutes < command
warning: commands will be executed using /bin/sh
job 36 at Sun Aug 19 16:22:00 2012
keyaming@ubuntu:~$
範例一:再過五分鐘後,將 /root/.bashrc 寄給 root 自己 [root@www ~]# at now + 5 minutes <==記得單位要加 s 喔! at> /bin/mail root -s "testing at job" < /root/.bashrc at> <EOT> <==這裡輸入 [ctrl] + d 就會出現 <EOF> 的字樣!代表結束! job 4 at 2009-03-14 15:38 # 上面這行資訊在說明,第 4 個 at 工作將在 2009/03/14 的 15:38 進行! # 而執行 at 會進入所謂的 at shell 環境,讓你下達多重指令等待運作! 範例二:將上述的第 4 項工作內容列出來查閱 [root@www ~]# at -c 4 #!/bin/sh <==就是透過 bash shell 的啦! # atrun uid=0 gid=0 # mail root 0 umask 22 ....(中間省略許多的環境變數項目).... cd /root || { <==可以看出,會到下達 at 時的工作目錄去執行指令 echo 'Execution directory inaccessible' >&2 exit 1 } /bin/mail root -s "testing at job" < /root/.bashrc # 你可以看到指令執行的目錄 (/root),還有多個環境變數與實際的指令內容啦! 範例三:由於機房預計於 2009/03/18 停電,我想要在 2009/03/17 23:00 關機? [root@www ~]# at 23:00 2009-03-17 at> /bin/sync at> /bin/sync at> /sbin/shutdown -h now at> <EOT> job 5 at 2009-03-17 23:00 # 您瞧瞧! at 還可以在一個工作內輸入多個指令呢!不錯吧! |
34Sun Aug 19 16:08:00 2012 a keyaming
keyaming@ubuntu:~$ atrm 34 //删除指定的任务
(4)crontab:在指定时间再执行
同at,但是任何出现在标准错误输出或标准输出上的数据都会寄给你,而不会显示在终端上。同时at也不会执行需要交互执行的程序,因为用户无法通过终端进行输入
crontab -l:列出目前工作调度
crontab -e:启动编辑器更新调度
crontab -r:删除所有的工作调度
代表意義 | 分鐘 | 小時 | 日期 | 月份 | 週 | 指令 |
數字範圍 | 0-59 | 0-23 | 1-31 | 1-12 | 0-7 | 呀就指令啊 |
比較有趣的是那個『週』喔!週的數字為 0 或 7 時,都代表『星期天』的意思!另外, 還有一些輔助的字符,大概有底下這些:
特殊字符 | 代表意義 |
*(星號) | 代表任何時刻都接受的意思!舉例來說,範例一內那個日、月、週都是 * , 就代表著『不論何月、何日的禮拜幾的 12:00 都執行後續指令』的意思! |
,(逗號) | 代表分隔時段的意思。舉例來說,如果要下達的工作是 3:00 與 6:00 時,就會是:
0 3,6 * * * command時間參數還是有五欄,不過第二欄是 3,6 ,代表 3 與 6 都適用! |
-(減號) | 代表一段時間範圍內,舉例來說, 8 點到 12 點之間的每小時的 20 分都進行一項工作:
20 8-12 * * * command仔細看到第二欄變成 8-12 喔!代表 8,9,10,11,12 都適用的意思! |
/n(斜線) | 那個 n 代表數字,亦即是『每隔 n 單位間隔』的意思,例如每五分鐘進行一次,則:*/5 * * * * command很簡單吧!用 * 與 /5 來搭配,也可以寫成 0-59/5 ,相同意思! |
例子:
keyaming@ubuntu:~$ crontab -e //进入编辑器编辑
crontab: installing new crontab
keyaming@ubuntu:~$ crontab -l
# m h dom mon dow command
*/1 * * * * ls > file
keyaming@ubuntu:~$ crontab -r
例子:指定另一个文件作为工作调度保存文件
keyaming@ubuntu:~$ cat other
*/1 * * * * ls > file
keyaming@ubuntu:~$ crontab other //指定other为工作调度保存文件
keyaming@ubuntu:~$ crontab -l
*/1 * * * * ls > file
keyaming@ubuntu:~$
7、/proc文件系统
在/proc目录下,存放着所有进程数据
例子:列出3663进程的数据
keyaming@ubuntu:~$ ls /proc/3663
attr cpuset io mountinfo pagemap smaps task
auxv cwd latency mounts personality stack wchan
cgroup environ limits mountstats root stat
clear_refs exe loginuid net sched statm
cmdline fd maps oom_adj schedstat status
coredump_filter fdinfo mem oom_score sessionid syscall