循序渐进学unix——上机记录(一)
Unix上机课已经进行5次了,信息量越来越大,需要记的东西也越来越多。于是决定把一些重要的东西记在这里跟大家分享。
在法国学计算机一个很大的感触就是实践所占的比重相当大,大课的信息量极大,很难记住什么东西,但是与之辅助的小课实在是十分奏效。小课以20人的小班为单位,这就是人少的好处,能保证每个人都掌握相关的知识。这边的课确实比在国内深多了,能看出老师确实有很高的水平,讲的很深很细致。
Unix系统课已经上了很多节,这里只记录上机课的一些个人认为重要的知识点。前两节小课主题是Bash 基本命令,再此不记录了,这里主要涉及通过unix下的c语言编程了解系统原理。
第一课
1, 写一个c程序,打印从终端传入的参数。注意当参数为*结果。
主函数生命为 void main(int argc, char ** argv)即可。argc为参数个数, argv为参数列表,注意argv[0]为命令本身,之后才为真正参数。
2,写一个程序,实现与"ls -il"相同的功能,即输出当前目录所有文件的有用信息,如访问模式,链接个数,最近修改时间等等。此函数利用了第一题的知识,即*会被翻译成当前目录下的所有文件。下面的程序在终端调用时参数为*。
主要使用stat()函数。见man lstat, 需要详细阅读。stat能把相应文件的所有信息返回至一个结构体里。获得所有者用户名时用到getpwuid,组用户名时用到getgrgid, 相关函数还有ctime. 代码:
#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <pwd.h>#include <grp.h>#include <time.h>#include <dirent.h>int main(int argc, char **argv){DIR *directory;struct dirent *file;struct stat fileStat;struct passwd *pwd;struct group *grp;char date[20];// le nom du répertoir à lire doit être passé en premier paramètreif(argc < 2) exit(-1);// ouverture du répertoireif((directory = opendir(argv[1])) == NULL) { perror("opendir"); exit(errno); }// pour tous les fichiers du répertoirewhile((file = readdir(directory)) != NULL){// collecte des infosif(lstat(file->d_name, &fileStat)) { perror("stat"); exit(errno); }// numéro d'I-noeudprintf("%d ", (int)fileStat.st_ino);// mise en forme des permissionsswitch(fileStat.st_mode & S_IFMT){case S_IFSOCK : printf("s"); break;case S_IFLNK : printf("l"); break;case S_IFREG : printf("-"); break;case S_IFBLK : printf("b"); break;case S_IFDIR : printf("d"); break;case S_IFCHR : printf("c"); break;case S_IFIFO : printf("p"); break;default : printf("?");} if((fileStat.st_mode & S_IRUSR) == S_IRUSR) printf("r"); else printf("-");if((fileStat.st_mode & S_IWUSR) == S_IWUSR) printf("w"); else printf("-");if((fileStat.st_mode & S_IXUSR) == S_IXUSR) if((fileStat.st_mode & S_ISUID) == S_ISUID) printf("s"); else printf("x");elseif((fileStat.st_mode & S_ISUID) == S_ISUID) printf("S"); else printf("-");if((fileStat.st_mode & S_IRGRP) == S_IRGRP) printf("r"); else printf("-");if((fileStat.st_mode & S_IWGRP) == S_IWGRP) printf("w"); else printf("-");if((fileStat.st_mode & S_IXGRP) == S_IXGRP)if((fileStat.st_mode & S_ISGID) == S_ISGID) printf("s"); else printf("x");elseif((fileStat.st_mode & S_ISGID) == S_ISGID) printf("S"); else printf("-");if((fileStat.st_mode & S_IROTH) == S_IROTH) printf("r"); else printf("-");if((fileStat.st_mode & S_IWOTH) == S_IWOTH) printf("w"); else printf("-");if((fileStat.st_mode & S_IXOTH) == S_IXOTH)if((fileStat.st_mode & S_ISVTX) == S_ISVTX) printf("t"); else printf("x");elseif((fileStat.st_mode & S_ISVTX) == S_ISVTX) printf("T"); else printf("-");// nombre de liens durprintf(" %d ", (int)fileStat.st_nlink);// nom du propriétaireif ((pwd = getpwuid(fileStat.st_uid)) != NULL)printf("%s ", pwd->pw_name);elseprintf("%d ", fileStat.st_uid);// nom du groupeif ((grp = getgrgid(fileStat.st_gid)) != NULL)printf("%s ", grp->gr_name);elseprintf("%d ", fileStat.st_gid);// taille du fichier en octetsprintf("%d ", (int)fileStat.st_size);// date de dernière modificationstrftime(date, 20, "%Y-%m-%d %H:%M", gmtime(&fileStat.st_mtime));printf("%s ", date);// nom du fichier et saut de ligneprintf("%s\n", file->d_name);}// si une erreur s'est produite sur "readdir"if(errno != 0) { perror("stat"); exit(errno); }return 0;}ok先到这,有时间继续整理