linux查看占用swap的进程脚本01#!/bin/bash0203##############################################################################04#
脚本功能
:
列出正在占用swap的进程。05###############################################################################0607echo
-e
PID/t/tSwap/t/tProc_Name0809#
拿出/proc目录下所有以数字为名的目录(进程名是数字才是进程,其他如sys,net等存放的是其他信息)10for
pid
in
`ls
-l
/proc
|
grep
^d
|
awk
'{
$9
}'|
grep
-v
[^0-9]`11do12
#
让进程释放swap的方法只有一个:就是重启该进程。或者等其自动释放。放13
#
如果进程会自动释放,那么我们就不会写脚本来找他了,找他都是因为他没有自动释放。14
#
所以我们要列出占用swap并需要重启的进程,但是init这个进程是系统里所有进程的祖先进程15
#
重启init进程意味着重启系统,这是万万不可以的,所以就不必检测他了,以免对系统造成影响。16
if
[
$pid
-eq
1
];then
continue;fi17
grep
-q
Swap
/proc/$pid/smaps
2>/dev/null18
if
[
$
-eq
0
];then19
swap=$(grep
Swap
/proc/$pid/smaps
/20
|
gawk
'{
sum+=$2;}
END{
sum
}')21
proc_name=$(ps
aux
|
grep
-w
$pid
|
grep
-v
grep
/22
|
awk
'{
for(i=11;i<=NF;i++){
printf(%s
,$i);
}}')23
if
[
$swap
-gt
0
];then24
echo
-e
${pid}/t${swap}/t${proc_name}25
fi26
fi27done
|
sort
-k2
-n
|
awk
-F'/t'
'{28
pid[NR]=$1;29
size[NR]=$2;30
name[NR]=$3;31}32END{33
for(id=1;id<=length(pid);id++)34
{35
if(size[id]<1024)36
printf(%-10s/t%15sKB/t%s/n,pid[id],size[id],name[id]);37
else
if(size[id]<1048576)38
printf(%-10s/t%152fMB/t%s/n,pid[id],size[id]/1024,name[id]);39
else40
printf(%-10s/t%152fGB/t%s/n,pid[id],size[id]/1048576,name[id]);41
}42}'
首先说说DIR这一结构体,以下为DIR结构体的定义:
struct __dirstream
{
void __fd;
char __data;
int __entry_data;
char __ptr;
int __entry_ptr;
size_t __allocation;
size_t __size;
__libc_lock_define (, __lock)
};
typedef struct __dirstream DIR;
DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息(摘自《UNIX环境高级编程(第二版)》)。函数 DIR opendir(const char pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:
struct dirent readdir(DIR dp);
void rewinddir(DIR dp);
int closedir(DIR dp);
long telldir(DIR dp);
void seekdir(DIR dp,long loc);
关于DIR结构,我们知道这么多就可以了,没必要去再去研究他的结构成员。
接着是dirent结构体,首先我们要弄清楚目录文件(directory file)的概念:这种文件包含了其他文件的名字以及指向与这些文件有关的信息的指针(摘自《UNIX环境高级编程(第二版)》)。从定义能够看出,dirent不仅仅指向目录,还指向目录中的具体文件,readdir函数同样也读取目录下的文件,这就是证据。以下为dirent结构体的定义:
struct dirent
{
long d_ino; / inode number 索引节点号 /
off_t d_off; / offset to this dirent 在目录文件中的偏移 /
unsigned short d_reclen; / length of this d_name 文件名长 /
unsigned char d_type; / the type of d_name 文件类型 /
char d_name [NAME_MAX+1]; / file name (null-terminated) 文件名,最长255字符 /
}
然后是怎么使用它读取进程信息。可以用这些函数来读取/proc下的文件夹,然后做一个判断,只要文件夹的名字开头是1-9的,就进入目录读取其中的status文件,然后输出信息。
代码
#include <stdioh>
#include <direnth>
#include <unistdh>
#include <stdlibh>
typedef struct{
pid_t pid;
char name[256];//进程名称
int vmsize;//虚拟内存信息
}proc_info_st;//保存读取的进程信息
#define PROC_NAME_LINE 1//名称所在行
#define PROC_PID_LINE 4//pid所在行
#define PROC_VMSIZE_LINE 12//虚拟内存所在行
#define BUFF_LEN 1024 //行缓冲区的长度
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
void read_proc(proc_info_st info,const char c_pid);//读取进程信息
int read_line(FILE fp,char buff,int b_l,int l);//读取一行
int main()
{
//打开目录
DIR dir;
struct dirent ptr;
if (!(dir = opendir("/proc")))
return 0;
//读取目录
while (ptr = readdir(dir))
{//循环读取出所有的进程文件
if (ptr->d_name[0] > '0' && ptr->d_name[0] <= '9')
{
//获取进程信息
proc_info_st info;
read_proc(&info,ptr->d_name);//读取信息
printf("pid:%d\npname:%s\nvmsize:%d\n",infopid,infoname,infovmsize);
printf("\n\n");//再空两行
}
}
}
/
说明:根据进程pid获取进程信息,存放在proc_info_st结构体中
输入:
/proc_info_st info 返回进程信息
/char c_pid 进程pid的字符串形式
/
void read_proc(proc_info_st info,const char c_pid)
{
FILE fp = NULL;
char file[512] = {0};
char line_buff[BUFF_LEN] = {0};//读取行的缓冲区
sprintf(file,"/proc/%s/status",c_pid);//读取status文件
if (!(fp = fopen(file,"r")))
{
printf("read %s file fail!\n",file);
return;
}
char name[32];
//先读取进程名称
if (read_line(fp,line_buff,BUFF_LEN,PROC_NAME_LINE))
{
sscanf(line_buff,"%s %s",name,(info->name));
}
fseek(fp,0,SEEK_SET);//回到文件头部
//读取进程pid
if (read_line(fp,line_buff,BUFF_LEN,PROC_PID_LINE))
{
sscanf(line_buff,"%s %d",name,&(info->pid));
}
fseek(fp,0,SEEK_SET);//回到文件头部
//读取进程vmsize
if (read_line(fp,line_buff,BUFF_LEN,PROC_VMSIZE_LINE))
{
sscanf(line_buff,"%s %d",name,&(info->vmsize));
}
fclose(fp);
}
/
说明:读取文件的一行到buff
输入:
/FILE fp 文件指针
/char buff 缓冲区
/int b_l 缓冲区的长度
/l 指定行
输出:
/true 读取成功
/false 读取失败
/
int read_line(FILE fp,char buff,int b_l,int l)
{
if (!fp)
return FALSE;
char line_buff[b_l];
int i;
//读取指定行的前l-1行,转到指定行
for (i = 0; i < l-1; i++)
{
if (!fgets (line_buff, sizeof(line_buff), fp))
{
return FALSE;
}
}
//读取指定行
if (!fgets (line_buff, sizeof(line_buff), fp))
{
return FALSE;
}
memcpy(buff,line_buff,b_l);
return TRUE;
}
如果你想更深入的了解一些东西可以参考下>
以上就是关于Linux查看占用swap的进程脚本全部的内容,包括:Linux查看占用swap的进程脚本、Linux下怎么读取多个进程的信息、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)