shell-进程操作
shell进程操作
一. 进程创建
创建方式:init自启动,crond/at定时启动,shell脚本启动
使用ulimit可以限制进程可以利用资源
让程序在后台运行
sleep 100 &
[1] 9298
制定程序名,查看进程ID
$ pidof sleep
2848 2846 2844
查看进程的内存映像
$ cat /proc/9298/maps
08048000-0804b000 r-xp 00000000 08:01 977399     /bin/sleep
0804b000-0804c000 rw-p 00003000 08:01 977399     /bin/sleep
0804c000-0806d000 rw-p 0804c000 00:00 0          [heap]
b7c8b000-b7cca000 r--p 00000000 08:01 443354
...
bfbd8000-bfbed000 rw-p bfbd8000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
二. 查看进程的属性和状态
2.1 ps查看进程属性
查看系统所有进程属性,TTY为?表示和终端没有关联
ps -ef	#查看全部进程属性
ps -C init #查看包含某个指定字符的进程属性
ps -U falcon #某个用户启动的进程属性
按照指定格式输出指定内容,这里会输出命令名和CPU使用率
ps -e -o "%C %c"
打印CPU使用率最高的前4个程序
ps -e -o "%C %c" | sort -u -k1 -r | head -5
7.5 firefox-bin
1.1 Xorg
0.8 scim-panel-gtk
0.2 scim-bridge
使用虚拟内存最大的 5 个进程
ps -e -o "%z %c" | sort -n -k1 -r | head -5
349588 firefox-bin
96612 xfce4-terminal
88840 xfdesktop
76332 gedit
58920 scim-panel-gtk
2.2 pstree查看亲缘关系
pstree打印系统的进程调用树
pstree
2.3 top动态查看进程信息
top,可以动态地查看进程的信息
top
很多参数:
-S 可以按照累计执行时间的大小排序查看
支持交互:
u 命令显示用户的所有进程	
k 命令杀掉某个进程
-n 1 选项可以采用它的批处理模式
top -n 1 -b
2.4 确保特定程序只有一个副本在运行
程序的名字唯一,相同代码不同文件名无法处理,把进程的$0存成一个文件,每次启动读取是否存在
pidfile=/tmp/$0".pid"
if [ -f $pidfile ]; then
        OLDPID=$(cat $pidfile)
        ps -e -o "%p" | tr -d " " | grep -q "^$OLDPID$"
        [ $? -eq 0 ] && exit
fi
echo $$ > $pidfile
#... 代码主体
trap "rm $pidfile"      0        #设置信号0的动作,当程序退出时触发该信号从而删除掉临时文件
三. 进程优先级
查看全部优先级,筛选出sleep的优先级
$ ps -e -o "%p %c %n" | grep sleep
3040 sleep             0
调整优先级,调整到1
renice 1 -p 3040
四. 结束进程
4.1 向进程发信号
kill pid
kill -l列出全部信号
暂停某个进程,通过kill发送SIGSTOP信号暂停某个程序,然后发送SIGCONT信号让它继续运行
$ sleep 50 &
[1] 11441
$ jobs
[1]+  Running                 sleep 50 &
$ kill -s SIGSTOP 11441   #这个等同于我们对一个前台进程执行CTRL+Z操作
$ jobs
[1]+  Stopped                 sleep 50
$ kill -s SIGCONT 11441   #这个等同于之前我们使用bg %1操作让一个后台进程运行起来
$ jobs
[1]+  Running                 sleep 50 &
$ kill %1                  #在当前会话(session)下,也可以通过作业号控制进程
$ jobs
[1]+  Terminated              sleep 50
4.2 查看进程退出状态
程序最后的return 0就是退出状态,执行完程序之后通过检查 $? 查看状态
默认的规则是:
0正常退出
-1是异常退出
五. 进程间通信
UNIX环境高级编程中介绍了很多方法:有名管道/无名管道,信号,message,队列,共享内存,信号量,套接字
在shell编程中,一般是管道和信号;
5.1 无名管道pipe
实现:把前一个进程的输出关联到管道的输入文件描述符,把下一个进程的输入关联到管道的输入文件描述符
关联过程通过输入输出重定向函数dup或者fcntl实现
ps -ef | grep init
5.2 有名管道
无名管道是一个文件,两个文件描述符;
有名管道也是个文件,有一个文件描述符,操作时满足先进先出。
如果读取空的fifo,会被阻塞;如果向满的fifo中写入,也会被阻塞,阻塞不会消耗资源;
$ mkfifo fifo_test    #通过mkfifo命令可以创建一个有名管道
$ echo "fewfefe" > fifo_test    #试图往fifo_test文件中写入内容,但是被阻塞,要另开一个终端继续下面的操作
$ cat fifo_test        #另开一个终端,记得,另开一个。试图读出fifo_test的内容
fewfefe
程序通过fifo,进行控制的代码:
应用程序的代码
#!/bin/bash
FIFO=fifo_test
while :;
do
    CI=`cat $FIFO`  #CI --> Control Info
    case $CI in
        0) echo "The CONTROL number is ZERO, do something ..."
        ;;
        1) echo "The CONTROL number is ONE, do something ..."
        ;;
        *) echo "The CONTROL number not recognized, do something else..."
        ;;
    esac
done
控制程序的代码
#!/bin/bash
FIFO=fifo_test
CI=$1
[ -z "$CI" ] && echo "the control info should not be empty" && exit
echo $CI > $FIFO
如果结合web cgi可以实现简单的远程控制,把control.sh放在web的cgi目录下,并做些修改使之符合cgi规范。
通过http://ipaddress_or_dns/cgi-bin/control.sh?0访问,?后的数字就是不同的控制码。
5.3 信号
CTRL+C发CGINT
有些信号有相应动作,有些信号进程会直接忽略,trap命令可以捕获,c语言用signal注册处理函数;
在代码中定义一个函数,然后调用trap把函数和信号关联起来;
0是个特殊的信号,在推出的时候会触发,可以在0信号中设定进程退出的清理工作;
#!/bin/sh
signal_handler() {
        echo "hello signal"
}
trap signal_handler 0
sleep 5
六. 作业和作业控制
运行的时候ctrl+z暂停
命令序列最后加&符号,后台运行
sleep 50 &
[1] 11137 #&返回作业号和进程号
fg把作业调到前台运行
fg %1
CTRL+Z让进程暂停
jobs查看作业情况
$ jobs            #查看当前作业情况,有一个作业停止
启动停止的作业
bg %1
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号