您的位置:首页 > 运维架构 > Linux

linux命令实现:cp

2015-05-07 10:26 447 查看
cp用于复制文件之类的操作

用法:cp [参数] file newfile (把file复制到newfile)

或:cp [参数] file1 file2 file3 ... dirname(把文件file1 file2 file ...复制到dirname目录下)

参数:

-a :相当于 -pdr 。

-d :若来源文件为连结文件的属性(link file),则复制该链接文件,而不是该链接文件所链接的文件。

-f :为强制 (force) 的意思,若有重复或其它疑问时,不会询问,直接复制。(一般alias cp='cp -i'时,使用)

-i :若目的文件已经存在时,在覆盖时会先询问。(覆盖不复制文件权限,只复制内容)

-l :复制硬链接文件,而不是硬链接文件所链接的内容(这个有点意思,大概就是,复制一个强连接文件,而不是把强连接文件的内容复制一遍,如果软链接是指针的话,强连接就是引用,-d 就是复制一个指针,-l 就是复制一个别名引用,不加的话,就是复制它们所指向的内容。可以百度linux文件系统,inode)

-p :连同文件的属性一起复制过去,而非使用预设属性。(这里的属性单指0744权限属性,还有atime最后读时间 ctime最后状态改变时间 mtime最后写时间 之类的一些属性 man cp原话是:-p same as --preserve=mode,ownership,timestamps)

-r :递归持续复制,用于目录的复制行为;

-s :复制成为软链接文件(symbolic link)。

-u:源文件比目的文件更新时,拷贝执行。

---------------------------------------------------------------------------------------------------------------------------------------------------------------

目前要实现的:

基本用法 -i ;

---------------------------------------------------------------------------------------------------------------------------------------------------------------

思路:

最基本思路无非就是读源文件,写目的文件。

实现读写需要read() write()之类的函数

实现同等权限需要stat(),fstat(),lstat()之类的函数

大概就是,通过main(int ac,char *av[]) 中的ac与*av获得源文件地址,然后打开该文件,读取该文件权限,通过读取到的目的文件的地址,建立目的文件,写入,关闭文件,完成。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

附上代码:

/*2015.5.9
 *cp01.c
 *
*/
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#define BUFFERSIZE 4096
#define MODE 00744
static int flag_i;
int main(int ac ,char *av[])
{
	int i=0,j=0,k=0,fnum=0;
	fnum=flag(ac,av);
	if(fnum<2) {
		fprintf(stderr,"miss file operand\n");
		return -1;
	}
	char avv[fnum][128];
	for(i=1;i<ac;i++)
	{
		if(av[i][0] != '-'){
			strcpy(avv[k++],av[i]);
			if(avv[k-1][strlen(avv[k-1])-1]=='/') avv[k-1][strlen(avv[k-1])-1]='\0';
			if(k<fnum&&(f_exist(avv[k-1])!=1)) {
				fprintf(stderr,"%s is not filename\n",av[i]);
				return -2;
			}
	/*		else if(k>2&&(f_exist(avv[k-1]))!=2){
				fprintf(stderr,"%s is not dirname\n");
				return -3;
			}*/
		}
	}
	int tp=f_exist(avv[fnum-1]);
	if(tp == 0){
		if(fnum>2) {
			fprintf(stderr,"%s is not dirname\n",avv[fnum-1]);
			return -4;
		}
		file_create(avv[0],avv[1]);
		file_to_file(avv[0],avv[1]);
	}
	else if(tp == 1){
		if(fnum>2){
			fprintf(stderr,"%s is not dirname\n",avv[fnum-1]);
			return -4;
		}
		if(flag_i){
			file_to_file(avv[0],avv[1]);
		}
		else {}			//do nothing 
	}
	else if(tp == 2){
		for(i=0;i<fnum-1;i++)
		{
			char *filename=avv[i],j=0,nfile[128];
			int len=strlen(avv[i]);
			/*--------------------*/
			while(j<len)												//	qu chu '/'
				if(avv[i][j++]=='/') filename = &avv[i][j-1];
			strcpy(nfile,avv[fnum-1]);
			len =strlen(nfile);
			nfile[len]='/';
			nfile[len+1]='\0';
			strcat(nfile,filename);
			/*create  legal path*/
			if(f_exist(nfile)==0){
				file_create(avv[i],nfile);
				file_to_file(avv[i],nfile);
			}
			else if(f_exist(nfile)==1){ if(flag_i) file_to_file(avv[i],nfile);
			}
		}
	}

return 0;
}
int file_create(char *patha,char *pathb)//创建新文件pathb,权限为patha的权限信息
{
	struct stat sta;
	int fdb;
	if(stat(patha,&sta) == -1 ){
		open(pathb,O_CREAT,MODE);
		return -1;
	}
	if(open(pathb,O_CREAT,sta.st_mode) == -1)
	{
		fprintf(stderr,"cp error\n");
		return -1;
	}
	return 0;
}
int flag(int ac,char *av[])//记录输入的选项-[]
{
	int flag_i=0,fnum=0;
	while(--ac){
		if(av[ac][0] == '-')
		{
			int i;
			for(i=1;i<strlen(av[ac]);i++)
				if(av[ac][i] == 'i') flag_i=1;
		}
		else fnum++;
	}
	return fnum;
} 
int f_exist(char *path)//判断文件类型
{
	struct stat st;
	int re;
	re = stat(path,&st);
	if(re == -1) {
		return 0;				//not exist
	}
	if((st.st_mode&S_IFDIR) == S_IFDIR)
		return 2;				//dir_file
	return 1;					//regular_file

}
int file_to_file(char *patha,char *pathb) //patha exist && pathb exist
{
	int fda,fdb;
	char BUF[BUFFERSIZE];
	fda=open(patha,O_RDONLY);
	if(fda == -1){
		perror(patha);
		return -1;
	}
	fdb=open(pathb,O_WRONLY);
	if(fdb == -1){
		perror(pathb);
		return -2;
	}
	ssize_t r_len,w_len;
	while((r_len=read(fda,BUF,BUFFERSIZE))!=0)
	{
		if(r_len == -1){
			perror(patha);
			return -3;
		}
		w_len=write(fdb,BUF,strlen(BUF));
		if(w_len != strlen(BUF)){
			perror(pathb);
			return -4;
		}
	}
	close(fda);
	close(fdb);
	return 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: