南邮GNU/Liunx复习总结

从标准输入文件中读取字符,并将读取字符输出至标准输出文件中。

注意

课本给出的代码缺少头文件#include (会弹出warning)

同时需要指定STDIN_FILENO为0.STDOUT_FILENO为1

six_one.c:

#include 
#include 
#include 
#include 
#define BUFSIZ 200
  int main(){
  char buf[BUFSIZ];
  int n;
  while((n=read(0,buf,BUFSIZ))>0)
  write(1,buf,n);
  exit(0);
}


对于read函数返回值n是具体读了多少字符,第一个参数是读取来源,第二个参数是读入存放在哪个缓冲区中(可以理解为存储的空间),第三个参数是一次性最大读多少

write同理

南邮GNU/Liunx复习总结_第1张图片

可以看出从标准输入,就会从标准输出,那么如果想要输出到其他文件呢,可以使用输出重定向。

南邮GNU/Liunx复习总结_第2张图片

可以看出1234的值输入到test_one文件中了,而如果想从别的文件输入(而不是屏幕)同理:

命令如下:./six_one

如果想从一个输入文件输入再传到输出文件中可以使用。six_one

这样test_one中的内容就到了test_two中了

南邮GNU/Liunx复习总结_第3张图片

如果不想在命令行中重定向,还可以使用dup重定向

比如将ls的标准输出重定向到ls.txt中(需要修改书上代码)

six_two.c

#include 
#include 
#include 
 int main(){
int fieId;
fieId=creat("ls.txt",0640);//第二个第一个数字0是指特殊类型(与文件类型无关),后面仨就是
正常文件所有者,文件所属用户组,其他用户
if (fieId<0){
fprintf(stderr,"error creating ls.txt\n");//stderr标准错误输出
exit(1);
}//上面整个一段话就是为了防止打开失败
dup2(fieId,1);//打开文件的文件描述符有fieId和1两个
close(fieId);//关掉fieId只留1
execl("/bin/ls","ls",(char *)NULL);//第三个写0会有warning,改成空指针
}
                                                                                      
                                                                                      
南邮GNU/Liunx复习总结_第4张图片

如果需要重定向输入将1改成0即可。

说句题外话:这个还是比较有用的,搭过oj的都知道题目输入都是存放在数据库或者文本形式存储在服务器中的,那么在线判题关键就是根据用户上传的程序,重定向输入,再重定向输出到一个规定格式的文本中,最后比较文本与标准答案即可。(当然真正做起来有很多问题,系统安全,进程并发,以及前后端数据具体传递就不赘述了)


查看指定文件的权限

这个关键就是掌握struct stat结构的内容及获取方式,给定路径即可通过stat函数获取struct stat结构,然后对于该结构体的内容需要的部分进行操作。

题目:给定路径,打印指定文件夹的权限(包括自身)

six_three.c

#include      
#include 
#include 
#include 
#include 
#include 
void mode_to_letter(int  mode,char *str)//从0~9共10个字符表示文件属性
{
	
    str[0]='-'; /*------这里的S_*****都是宏定义,用来判断模式属性-*/
          	
    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';/*--用户的三个属性-*/
    else str[1]='-';
    if(mode & S_IWUSR) str[2]='w';
    else str[2]='-';
    if(mode & S_IXUSR) str[3]='x';
    else str[3]='-';

    if(mode & S_IRGRP) str[4]='r';/*--组的三个属性-*/
    else str[4]='-';
    if(mode & S_IWGRP) str[5]='w';
    else str[5]='-';
    if(mode & S_IXGRP) str[6]='x';
    else str[6]='-';

    if(mode & S_IROTH) str[7]='r';/*-其他人的三个属性-*/
    else str[7]='-';
    if(mode & S_IWOTH) str[8]='w';
    else str[8]='-';
    if(mode & S_IXOTH) str[9]='x';
    else str[9]='-';

    str[10]='\0';
}

int main(int argc,char *argv[])
{
    struct stat sb;
    char str[12]; 
    if(argc!=2){//给定的变量没有1个(0是自己,1是查看权限的文件夹)
        fprintf(stderr,"Usage: %s \n",argv[0]);
        exit(EXIT_FAILURE);
    }

    if(stat(argv[1],&sb)==-1){//获得文件参数)
        perror("stat");//失败的话提示
        exit(EXIT_FAILURE);
    }

    printf("Mode:%lo\n",(unsigned long)sb.st_mode);//直接通过函数获得
    mode_to_letter(sb.st_mode,str);//自己实现的转化成字符串
    printf("Mode:%s\n",str);
    return 0;
}

这里采用/home/ubuntu的路径进行了验证


南邮GNU/Liunx复习总结_第5张图片


书上还有改变文件权限,实质都是一样的,首先根据路径(argv[1])获得stat结构体,然后对其进行操作(改变权限就用chown函数)


目录操作部分,就是掌握struct dirent内容及获取方式(argv[1])根据路径获取结构体

题目:指定路径,根据路径获取该目录下所有文件。

six_four.c

#include 
#include 
#include 
#include 
#include 
int main(int argc,char* argv[]){
DIR *dirp;
struct dirent *direntp;
if ((dirp=opendir(argv[1]))==NULL){//给定目录,获得返回目录值
fprintf(stderr,"%s\n",strerror(errno));//标准错误打印
exit(1);
}
while((direntp=readdir(dirp))!=NULL)//遍历目录下所有文件(根据目录获取文件)
printf("%s\n",direntp->d_name);//打印文件名
exit(0);
}


南邮GNU/Liunx复习总结_第6张图片

嘛,中间乱入一些奇怪的东西就忽视吧...


最后一个目录操作提高的题目,遍历当前目录下所有以.sh结尾的文件

思路和刚才一样,根据路径获取目录->获取文件->获取文件名->判断文件名最后3位是不是.sh

six_five.c

#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    DIR *aDir = NULL;
    struct dirent *a = NULL;
    size_t length;
    if (argc == 1)//只有一个参数,没有给定路径
    {
        printf("usage: ./readDir dirName");
        exit(-1);
    }
    aDir = opendir(argv[1]);//打开目录
    if (aDir == NULL)//如果打开目录失败
    {
        printf("not a dir\n");
        exit(-2);
    }
    while((a = readdir(aDir)) != NULL)//根据目录遍历文件
    {
        length = strlen(a->d_name);//获得文件名长度
        if (length > 3 && strcmp(a->d_name + length - 3, ".sh") == 0)//文件名长度大于3并且最后3位是.sh
            printf("%s\n", a->d_name);
    }
    return 0;
}



南邮GNU/Liunx复习总结_第7张图片

你可能感兴趣的:(南邮GNU/Liunx复习总结)