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
posted @ 2016-08-15 19:17  zhangshihai1232  阅读(296)  评论(0)    收藏  举报