我是靠谱客的博主 朴实煎饼,最近开发中收集的这篇文章主要介绍UNIX编程学习——cp、ls、pwd、who指令实现cp指令ls -l指令pwd指令who指令,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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,&current_user,num)==num)
        show_info(&current_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指令所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部