概述
cp指令
在unix操作系统中,cp指令用于将源文件复制到目标文件。
实现cp指令
其实现原理较为简单,不断读取源文件内容,直到全部读取,并将读取字符不断写入到目标文件中。
代码
#include"apue.h"
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#define BUFFSIZE 4096
int main(int argc,char* argv[])
{
int fd_in,fd_out,rdnum;
char* Buffer[BUFFSIZE];
if(argc!=3)
err_sys("Error in number of parametersn");
if((fd_in=open(argv[1],O_RDONLY))<0)
err_sys("open source file errorn");
if(((fd_out=open(argv[2],O_CREAT|O_WRONLY,0644))<0))
err_sys("open target file error");
printf("%dn",fd_out);
while((rdnum=read(fd_in,Buffer,BUFFSIZE))>0)
if(write(fd_out,Buffer,rdnum)!=rdnum)
err_sys("write error!n");
if(rdnum<0)
err_sys("read error!n");
if(close(fd_in)||close(fd_out))
err_sys("close error!n");
}
ls -l指令
ls -l指令是常用指令之一,该指令输出指定文件加下所有文件的读写执行权限,所属用户,用户所在组,链接数及最终修改时间。具体信息参考:
https://blog.csdn.net/zhuoya_/article/details/77418413
实现ls -l指令
ls -l显示的所有信息都存储在stat结构体中。通过fstatat函数可以获取对应文件的属性。之后将其转换成对应的格式输出即可。
注意:
在stat结构体中存放的是用户ID和用户组ID,需要通过特定的方式将其转换成用户名。
代码
#include"apue.h"
#include<sys/stat.h>
#include<dirent.h>
#include<stdio.h>
#include<grp.h>
#include<pwd.h>
#include<time.h>
#include<fcntl.h>
#include<sys/stat.h>
void mode_to_letter(int mode,char*str)
{
strcpy(str,"----------");//输出文件权限位
if(S_ISDIR(mode)) str[0]='d';
if(S_ISCHR(mode)) str[0]='c';
if(S_ISBLK(mode)) str[0]='b';
if(mode&S_IRUSR) str[1]='r';
if(mode&S_IWUSR) str[2]='w';
if(mode&S_IXUSR) str[3]='x';
if(mode&S_IRGRP) str[4]='r';
if(mode&S_IWGRP) str[5]='w';
if(mode&S_IXGRP) str[6]='x';
if(mode&S_IROTH) str[7]='r';
if(mode&S_IWOTH) str[8]='w';
if(mode&S_IXOTH) str[9]='x';
}
char* gid_to_name(gid_t gid)
{
struct group* pw_ptr;
static char numstr[10];
if((pw_ptr=getgrgid(gid))==NULL)//将用户组ID转换为用户组名
{
sprintf(numstr,"%d",gid);
return numstr;
}
else
return pw_ptr->gr_name;
}
char* uid_to_name(uid_t uid)
{
struct passwd *pw_ptr,*getpwuid(uid_t);
static char numstr[10];
if((pw_ptr=getpwuid(uid))==NULL)//将用户ID转换为用户名
{
sprintf(numstr,"%d",uid);
return numstr;
}
else
return pw_ptr->pw_name;
}
void show_file_info(char* name,struct stat* info)
{
char mode[11];
mode_to_letter(info->st_mode,mode);
printf("%s ",mode);
printf("%-4d",(int)info->st_nlink);
printf("%-8s",uid_to_name(info->st_uid));
printf("%-8s",uid_to_name(info->st_gid));
printf("%8ld ",(long)info->st_size);
printf("%.12s ",4+ctime(&info->st_mtime));
printf("%sn",name);
}
void do_stat(char* pathname,int fd)
{
struct stat info;
if(fstatat(fd,pathname,&info,0)==-1)//使用fstatat而非stat是因为前者提供了fd参数,便于输出指定文件夹中的信息
err_sys("stat error");
show_file_info(pathname,&info);//将获取的文件信息按照格式显示
}
void do_ls(char* name)
{
DIR* openDir;
struct dirent* cur;
if((openDir=opendir(name))==NULL)//打开指定文件夹
err_sys("opendir error!");
int fd=open(name,O_RDONLY);
while((cur=readdir(openDir))!=NULL)
if(strcmp(cur->d_name,".")!=0&&strcmp(cur->d_name,"..")!=0)//.和.. 文件不显示
{
do_stat(cur->d_name,fd);
}
closedir(openDir);
}
int main(int argc,char* argv[])
{
if(argc==1)
do_ls(".");
else
{
while(--argc)
{
printf("%s:n",*++argv);
do_ls(*argv);
}
}
}
pwd指令
pwd指令输出从根目录到当前文件夹的路径。
实现pwd指令
从当前文件夹向上不断查找,直到根目录。每个目录中都至少有两个文件:“.”和". .",其中 . 指向当前文件夹,**. .**指向上一级目录(根目录中两文件都指向本身)。实现pwd指令的思路是通过. .打开上一级文件夹,从上一级文件夹中搜索出本层文件夹的名字,再返回上上一级文件夹,查找出上一级文件夹的名字,不断递归,直到根目录。
代码
#include"apue.h"
#include<sys/stat.h>
#include<dirent.h>
int i_node_num(char* name)
{
struct stat info;
if(stat(name,&info)==-1)
{
printf("%s ",name);
err_sys("stat error!");
}
return info.st_ino;//返回本层文件夹i节点
}
void findname(char* buf,int i_node,int length)//查找对应i节点编号的文件名
{
DIR* dir;
struct dirent* cur;
if((dir=opendir("."))==NULL)
{
err_sys("opendir error");
}
while((cur=readdir(dir))!=NULL)
{
if(cur->d_ino==i_node)
{
strncpy(buf,cur->d_name,length);
closedir(dir);
return ;
}
}
}
void printfpwd(int i_node)
{
char name[512];
int my_node;
if(i_node_num("..")!=i_node)//判断是否是根目录
{
chdir("..");//切换工作目录
findname(name,i_node,512);//在上级目录中查找文件名
my_node=i_node_num(".");
printfpwd(my_node);//递归
printf("/%s",name);
}
}
int main()
{
printfpwd(i_node_num("."));
printf("n");
exit(0);
}
who指令
who指令输出当前登陆到系统的用户,终端名,修改时间。
实现who指令
ubuntu系统将用户信息存放在,/var/run/utmp,系统为每个用户信息维护了一个utmp结构体。我们只需要将其中的ut_user,ut_line,ut_tv属性转换成对应格式输出即可。
代码
#include"apue.h"
#include<fcntl.h>
#include<utmp.h>
#include<time.h>
void show_info(struct utmp* p)
{ if(p->ut_type!=7)//判断用户类型,只有7才是当前登陆到系统中的用户。
return ;
printf("%-8.8s",p->ut_user);
printf(" ");
printf("%-8.8s",p->ut_line);
printf(" ");
//printf("%s",ctime((time_t*)(&(p->ut_tv).tv_sec)));
struct tm* ti=localtime(((time_t*)&(p->ut_tv.tv_sec)));
printf("%d-%d-%d,%d:%d:%d",ti->tm_year,ti->tm_mon+1,ti->tm_mday,ti->tm_hour,ti->tm_min,ti->tm_sec);
printf(" ");
#ifdef SHOWHOST
printf("(%s)",p->ut->host);
#endif
printf("n");
}
int main(void)
{
struct utmp current_user;
int num=sizeof(current_user);
int fd;
if((fd=open("/var/run/utmp",O_RDONLY))<0)
err_sys("open utmp error!n");
while(read(fd,¤t_user,num)==num)
show_info(¤t_user);
close(fd);
exit(0);
}
每周进步一点点,坚持,加油!
最后
以上就是朴实煎饼为你收集整理的UNIX编程学习——cp、ls、pwd、who指令实现cp指令ls -l指令pwd指令who指令的全部内容,希望文章能够帮你解决UNIX编程学习——cp、ls、pwd、who指令实现cp指令ls -l指令pwd指令who指令所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复