进程的监控与管理
在linux系统中,进程ID(用PID表示)是区分不同进程的唯一标识,它们的大小是有限制的,最大ID为32768,用UID和GID分别表示启动这个进程的用户和用户组。
所有的进程都是PID为1的init进程(centos7.x版本是systemd进程)的后代。
内核在系统启动的最后阶段启动init进程,因而,这个进程是linux下所有进程的父进程,用PPID表示父进程。
常用的进程管理命令有:
ps、pstree、top、lsof、pgrep、kill、killall
ps命令
功能说明
ps命令显示系统进程在瞬间的运行动态,其格式如下:
ps [选项]
ps的选项非常之多,这里我们仅仅介绍常用的选项
-a
显示所有用户的进程,包含每个程序的完整路径-x
显示所有系统程序,包括那些没有终端的程序-u
显示使用者的名称和起始时间f
树状结构显示,表明相互关系-f
详细显示程序执行的路径-e
将除内核进程以外所有进程的信息写到标准输出- o 属性… 选项显示定制的信息 pid、cmd、%cpu、%mem
- USER: 行程拥有者
- PID: pid
- %CPU: 占用的 CPU 使用率
- %MEM: 占用的内存使用率
- VSZ: 占用的虚拟内存大小
- RSS: 占用的物理内存大小
- TTY: 终端的次要装置号码 (minor device number of tty)
- STAT: 该行程的状态:
- D: 不可唤醒的休眠
- R: 正在执行中
- S: 休眠
- T: 停止
- Z: 僵死
- W: 没有足够的记忆体分页可分配
- <: 高优先序的行程
- N: 低优先序的行程
- +: 前台进程
- l: 多线程进程
- L:内存分页并带锁
- s: session leader,会话(子进程)发起者
- start: 行程开始时间
- lstart: 详细的开始时间
- etime: 执行的时间
- commond:所执行的指令
常用组合:
ps -ef、ps auxf
ps -axo user,pid,%cpu,%mem,vsz,tty,stat,start,time,command -k %mem
指定显示user,pid,%cpu,%mem,vsz,tty,stat,start,time,command并按照%mem排序
pstree
pstree 以树状显示进程
选项
- -a, --arguments 显示命令行参数
- -A, --ascii 使用 ASCII 画线字符
- -c, --compact 不压缩相同的子树
- -G, --vt100 使用VT100画线字符
- -l, --long 不截断长行
- -n, --numeric-sort 按 PID 排序输出
- -p, --show-pids 显示 PID;暗示-c
- -s, --show-parents 显示所选进程的父进程
- -U, --unicode 使用 UTF-8 (Unicode) 画线字符
lsof
list open files查看当前系统文件的工具。
在linux环境下,一切皆文件,用户通过文件不仅可以访问常规数据,还可以访问网络连接和硬件如传输控制协议 (TCP) 和用户数据报协议 (UDP)套接字等,系统在后台都为该应用程序分配了一个文件描述符
命令参数
-a
:列出打开文件存在的进程-c <进程名>
:列出指定进程所打开的文件-p <进程号>
:显示指定进程号所打开或依赖的文件-u <用户名>
:显示用户打开的文件+D <目录>
:递归列出目录下被打开的文件+d <目录>
:列出目录下被打开的文件,不递归-g
:列出GID号进程详情- -
d <文件号>
:列出占用该文件号的进程-n <目录>
:列出使用NFS的文件-i <条件>
:列出符合条件的进程(4,6,协议,:端口,@ip )-n
: 不反向解析网络名字
lsof -p PID:PID是进程号,通过进程号显示程序打开的所有文件及相关进程
lsof -i 通过监听指定的协议、端口、主机等信息,显示符合条件的进程信息。
示例
进程管理
- 查看由登陆用户启动而非系统启动的进程
lsof /dev/pts/1- 指定进程号,可以查看该进程打开的文件
lsof -p 9527文件管理
- 查看指定程序打开的文件
lsof -c httpd- 查看指定用户打开的文件
lsof -u root | more- 查看指定目录下被打开的文件
lsof +D /var/log/
lsof +d /var/log/
参数+D为递归列出目录下被打开的文件,参数+d为列出目录下被打开的文件网络管理
查看所有网络连接
lsof -i –n
lsof [email protected]
通过参数-i查看网络连接的情况,包括连接的ip、端口等以及一些服务的连接情况,例如:sshd等。也可以通过指定ip查看该ip的网络连接情况查看端口连接情况
lsof -i :80 -n
通过参数-i:端口可以查看端口的占用情况,-i参数还有查看协议,ip的连接情况等查看指定进程打开的网络连接
lsof -i –n -a -p 9527
参数-i、-a、-p等,-i查看网络连接情况,-a查看存在的进程,-p指定进程查看指定状态的网络连接
lsof -n -P -i TCP -s TCP:ESTABLISHED-n:no host names
-P:no port names
-i TCP指定协议
-s指定协议状态
通过多个参数可以清晰的查看网络连接情况、协议连接情况等
lsof常用组合:
lsof -c sshd
lsof -g 4918
lsof -i :80
lsof -i tcp:25
lsof输出解析:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
init 1 root cwd DIR 8,1 4096 2 /
init 1 root rtd DIR 8,1 4096 2 /
init 1 root txt REG 8,1 150584 654127 /sbin/init
udevd 415 root 0u CHR 1,3 0t0 6254 /dev/null
udevd 415 root 1u CHR 1,3 0t0 6254 /dev/null
udevd 415 root 2u CHR 1,3 0t0 6254 /dev/null
udevd 690 root mem REG 8,1 51736 302589 /lib/x86_64-linux-gnu/libnss_files-2.13.so
syslogd 1246 syslog 2w REG 8,1 10187 245418 /var/log/auth.log
syslogd 1246 syslog 3w REG 8,1 10118 245342 /var/log/syslog
dd 1271 root 0r REG 0,3 0 4026532038 /proc/kmsg
dd 1271 root 1w FIFO 0,15 0t0 409 /run/klogd/kmsg
dd 1271 root 2u CHR 1,3 0t0 6254 /dev/null
lsof输出各列信息的意义如下:
- COMMAND:进程的名称
- PID:进程的id
- USER:进程所有者
- FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
- TYPE:文件类型,如DIR、REG等
- DEVICE:指定磁盘的名称
- SIZE:文件的大小
- NODE:索引节点(文件在磁盘上的标识)
- NAME:打开文件的确切名称
lsof用法
$ lsof test.txt #显示开启文件test.txt的进程
$ lsof -c abc #显示abc进程现在打开的文件
$ lsof -cp 1234 #列出进程号为1234的进程所打开的文件
$ lsof -g gid #显示归属gid的进程情况
$ lsof +d /usr/local/ #显示/usr/local/目录下被进程开启的文件
$ lsof +D /usr/local/ #同上,但是会搜索目录下的目录(即递归搜索),时间较长
$ lsof -d 4 #显示fd为4的进程
$ lsof -i #用以显示符合条件的进程情况
$ lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
46 --> IPv4 or IPv6
protocol --> TCP or UDP
hostname --> Internet host name
hostaddr --> IPv4地址
service --> /etc/service中的 service name (可以不止一个)
port --> 端口号 (可以不止一个)
$ lsof `which httpd` #查看哪个进程在使用apache的可执行文件
$ lsof /etc/passwd #查看哪个进程在占用/etc/passwd
$ lsof /dev/hda6 #查看哪个进程在占用hda6
$ lsof /dev/cdrom #查看哪个进程在占用光驱
$ lsof -c sendmail #查看sendmail进程现在打开的文件
$ lsof -c courier -u ^zahn #显示出哪些文件被以courier打头的进程打开,但是并不属于用户zahn
$ lsof -p 30297 #列出进程id为30297的进程所打开的文件
$ lsof -D /tmp #显示所有在/tmp目录下打开文件的进程
$
$ lsof -u1000 #查看uid是1000的用户的进程的文件使用情况
$ lsof -utony #查看用户tony的进程的文件使用情况
$ lsof -u^tony #查看不是用户tony的进程的文件使用情况(^是取反的意思)
$ lsof -i #显示所有已经打开的端口
$ lsof -i:80 #查看80端口被哪个进程占用
$ lsof -i -U #显示所有打开的端口和UNIX domain文件
$ lsof -i UDP@[url]www.akadia.com:123 #显示哪些进程打开了到www.akadia.com的UDP的123(ntp)端口的链接
$ lsof -i [email protected]:ftp -r #不断查看目前ftp连接的情况(-r,lsof会永远不断的执行,直到收到中断信号,+r,lsof会一直执行,直到没有档案被显示,缺省是15s刷新)
$ lsof -i [email protected]:ftp -n #lsof -n 不将IP转换为hostname,缺省是不加上-n参数
pgrep
利用pgrep查询进程ID
pgrep是通过程序的名字来查询进程pid的工具,它通过检查程序在系统中活动的进程,输出进程属性匹配命令行上指定条件的进程的ID
pgrep [选项] <pattern>
选项
-d<string>
指定输出分隔符-l
, --list-name 列出PID和进程名-a
, --list-full 列出 PID 和完整的命令行-v
, --inverse 否定匹配-c
, --count 匹配进程的计数-f
, --full 使用完整的进程名来匹配-g <PGID,...>
, --pgroup 匹配列出的进程组 ID-G <GID,...>
, --group 匹配真实组 ID-n
, --newest 选择最近开始的-o
, --oldest 选择最近最少开始-P <PPID,...>
, --parent 只匹配给定父进程的子进程-s <SID,...>
, --session 匹配会话 ID-t <tty,...>
, --terminal通过控制终端匹配-u <ID,...>
, --euid 匹配有效 UID-U <ID,...>
, --uid 匹配真实 ID-x
, --exact 与命令名完全匹配-F <file>
, --pidfile从文件中读取 PID-L
, --logpidfile 如果 PID 文件未锁定则失败
$ pgrep -d '*' ssh
876*1265*1734
$ pgrep -a ssh
876 /usr/sbin/sshd -D
1265 sshd: root@pts/0
1734 sshd: root@pts/1
$ pgrep -l ssh
876 sshd
1265 sshd
1734 sshd
# 查看父PID为1的ssh进程
$ pgrep -P1 -l ssh
kill
kill命令:向进程发送控制信号,以实现对进程管理,每个信号对应一个数字,信号名称以SIG开头(可省略),不区分大小写
显示当前系统可用信号: kill –l
或者 trap -l
- 1 ----> SIGHUP 无须关闭进程而让其重读配置文件
- 2 ----> SIGINT 中止正在运行的进程;相当于Ctrl+c
- 3 ----> SIGQUIT 相当于ctrl+\
- 9 ----> SIGKILL 强制杀死正在运行的进程
- 15 ----> SIGTERM 终止正在运行的进程
- 18 ----> SIGCONT 继续运行
- 19 ----> SIGSTOP 后台休眠
指定信号的方法 :
(1) 信号的数字标识:2,9,15
(2) 信号完整名称:SIGHUP
(3) 信号的简写名称:HUP
特殊:0 试探进程,如果有这个进程,不返回任何东西,如果没有,报错!
配合echo $?
查看输出,如果输出为0,则表示正常执行,如果输出为其他数字,则表示执行失败!
常用信号 2,9,15
例如
强制关闭pid为1234的进程
kill -9 1234
killall
用killall终止一个进程
killall也是关闭进程的一个命令,与kill不同的是,killall后面跟的是进程的名字,而不是进程的PID,因而,killall可以终止一组进程。
killall的使用语法为:
killall [信号类型] 进程名称
- 信号类型:与kill命令中信号类型的含义相同。
- 进程名称:进程对应的名称,例如java、httpd、mysqld、sshd、sendmail等
作业管理
Linux的作业控制
- 前台作业:通过终端启动,且启动后一直占据终端
- 后台作业:可通过终端启动,但启动后即转入后台运行(释放终端)
让作业运行于后台
- (1) 运行中的作业:
Ctrl+z
- (2) 尚未启动的作业:
COMMAND &
后台作业虽然被送往后台运行,但其依然与终端相关;退出终端,将关闭后台作业。如果希望送往后台后,剥离与终端的关系
nohup COMMAND &>/dev/null &
screen;COMMAND
查看当前终端所有作业:jobs
作业控制:
fg [[%]JOB_NUM]
:把指定的后台作业调回前台
bg [[%]JOB_NUM]
:让送往后台的作业在后台继续运行
kill [%JOB_NUM]
: 终止指定的作业
前台-----转----》后台
Ctrl+z
但是会停止--------》希望在后台执行bg [[%]JOB_NUM]
后台----转----》前台
fg [[%]JOB_NUM]
关闭后台任务
kill [%JOB_NUM]
并行运行
同时运行多个进程,提高效率
- 方法1
vi all.sh
f1.sh&
f2.sh&
f3.sh&
- 方法2
(f1.sh&);(f2.sh&);(f3.sh&)
- 方法3
{ f1.sh& f2.sh& f3.sh& }
任务调度进程crond的使用
crond的概念和分类
crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似。Linux下的任务调度分为两类,系统任务调度和用户任务调度。
- 系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。
- 用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab 文件都被保存在 /var/spool/cron目录中。其文件名与用户名一致。
crontab常用的使用格式
crontab [-u user] [file]
crontab [-u user] [-e|-l|-r |-i]
选项含义如下:
-u user
:用来设定某个用户的crontab服务,例如,“-u ixdba”表示设定ixdba用户的crontab服务,此参数一般有root用户来运行。- file:file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。
-e
:编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。-l
:显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。- -r:从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。
- -i:在删除用户的crontab文件时给确认提示。
常用组合:
crontab -e
;crontab -l
crontab文件的含义
用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:
minute hour day month week command
其中:
- minute: 表示分钟,可以是从0到59之间的任何整数。
- hour:表示小时,可以是从0到23之间的任何整数。
- day:表示日期,可以是从1到31之间的任何整数。
- month:表示月份,可以是从1到12之间的任何整数。
- week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
- command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。
在以上各个字段中,还可以使用以下特殊字符:
- 星号(
*
):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。 - 逗号(
,
):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9” - 中杠(
-
):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6” - 正斜线(
/
):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。
crontab应用举例
0 */3 * * * /usr/local/apache2/apachectl restart
表示每隔3个小时重启apache服务一次。
30 3 * * 6 /webdata/bin/backup.sh
表示每周六的3点30分执行/webdata/bin/backup.sh脚本的操作。
0 0 1,20 * * fsck /dev/sdb8
表示每个月的1号和20号检查/dev/sdb8磁盘设备。
10 5 */5 * * echo "">/usr/local/apache2/log/access_log
表示每个月的5号、10号、15号、20号、25号、30号的5点10分执行清理apache日志操作。
每3小时echo和wall命令
0 */3 * * * centos /bin/echo “howdy”; wall “welcome to Magedu!”
* * * * * for min in 0 1 2; do echo "hi"; sleep 20; done
每20秒执行一次
echo "hi"
sleep命令:
sleep NUMBER[SUFFIX]...
SUFFIX:
- s: 秒, 默认
- m: 分
- h: 小时
- d: 天
使用crontab工具的注意事项
- 注意环境变量问题
有时我们创建了一个crontab,但是这个任务却无法自动执行,而手动执行这个任务却没有问题,这种情况一般是由于在crontab文件中没有配置环境变量引起的。 - 注意清理系统用户的邮件日志
可以在crontab文件中设置如下形式,忽略日志输出:
0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1
- 系统级任务调度与用户级任务调度
系统级任务调度主要完成系统的一些维护操作(比如定时重启机器),用户级任务调度主要完成用户自定义的一些任务,可以将用户级任务调度放到系统级任务调度来完成(不建议这么做),但是反过来却不行。