# 定义目录变量,便于引用
A=/tmp/A
B=/tmp/B
C=/tmp/C
ls "$B"|awk '{print $n}' >line
# 主程序
for filename in `cat line`
do
# ! -f 判断文件名 -d 判断目录/ 是否在路径下存在,如果精确匹配需要用到md5sum!
if [ ! -f "$A"/"$filename" ] then
# 提示信息,可删除
echo $filename 在"$A"不存在,正复制到"$C"目录!
# cp -rf 在C目录不存在时直接创建
cp -rf "$B"/$filename "$C"
fi
done
# 清除生成的文件列表文件
rm -rf line #!/bin/bash
A=/tmp/A
B=/tmp/B
C=/tmp/C
ls "$B"|awk '{print $n}' >line
for filename in `cat line`
do
if [ ! -f "$A"/"$filename" ] then
echo $filename 在"$A"不存在,正复制到"$C"目录!
cp -rf "$B"/$filename "$C"
fi
done
rm -rf line
几点问题:
1)管道符后面的命令都是要新建shell去执行的,也就是说,while循环中的内容都不是在当前shell中执行,而array是在while循环中赋值的,所以当执行完while循环返回到当前shell后,array的值丢失。
这一点必须清楚:新建shell可以继承当前shell的变量,相当于拷贝了变量的一个副本,而命令执行完退出新建shell后,新建shell中的变量也都随之湮灭。
2)awk本身就是逐行读入并处理文件的,while read line 也是这样,功能上有重叠,一般用其一即可,特殊情况除外。
3)这就一个字段而已,何必用数组array呢?当然,你要用数组也是可以的,只是我有点不理解。
4)如果$1是一个文件,不需要cat后再通过管道符传递,awk本身就可以直接处理文件
awk -F= '$1 ~ /'$args'/ {print $2}' $1 就可以,管道符能少用则少用。
修改建议:
保留awk,去除while read line,试试:
array=(`awk -F= '$1 ~ /'$args'/ {print $2}' $1`)echo ${array[0]}
如果要保留你的while read line结构,那么:
while read linedo
array=(`echo "$line" | awk -F= '$1 ~ /'$args'/ {print $2}'`)
done <$1
echo ${array[0]}
首先说说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 <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
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",info.pid,info.name,info.vmsize)
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 = 0i <l-1i++)
{
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
}
如果你想更深入的了解一些东西可以参考下http://www.linuxprobe.com/chapter-09.html,希望能对你有帮助
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)