ls -lai
的功能ls -l #以長格式顯示目錄下的內容列表。輸出的信息從左到右依次包括文件名,文件類型、權限模式、硬鏈接數、全部者、組、文件大小和文件的最後修改時間等 ls -a #顯示全部檔案及目錄(ls內定將檔案名或目錄名稱爲「.」的視爲影藏,不會列出) ls -i #顯示文件索引節點號(inode number),一個索引節點表明一個文件
stat函數:html
#include<sys/stat.h> int stat(const char * path,struct stat * buf); /*將path參數(文件或目錄)的文件信息寫到buf中,buf爲傳出參數*/
stat結構體:node
struct stat{ dev_t st_dev; //設備id號(無需用到) ino_t st_ino; //索引節點號 mode_t st_mode; //權限與文件類型 nlink_t st_nlink; //硬連接數 uid_t st_uid; //用戶id ggid_t st_gid; //所在組id dev_t st_rdev; //設備id,對於特殊文件纔有(無需用到) off_t st_size; //大小,較爲經常使用 blksize_t st_blocks; //文件系統I/O的塊大小(無需用到) blkcnt_t st_blksize; //分配的512B(扇區)塊數(無需用到) time_t st_atime; //最後的訪問時間(無需用到) time_t st_mtime; //最後的修改時間,較爲經常使用 time_t st_ctime; //最後的狀態改變時間(無需用到) }
所以,需對上述相應字段格式化處理。編程
判斷文件類型的宏函數:數組
S_ISREG(m) is it a regular file? //判斷是不是普通文件 S_ISDIR(m) directory? //判斷是不是目錄 S_ISCHR(m) character device? //判斷是不是字符設備 S_ISBLK(m) block device? //判斷是不是塊設備 S_ISFIFO(m) FIFO (named pipe)? //判斷是不是管道文件 S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.)//判斷使是不是符號連接(軟鏈接) S_ISSOCK(m) socket? (Not in POSIX.1-1996.) //判斷是不是SOCKET文件
文件權限宏變量:服務器
S_IRUSR 00400 //用戶有讀權限 S_IWUSR 00200 //用戶有寫權限 S_IXUSR 00100 //用戶有執行權限 S_IRGRP 00040 //組有讀權限 S_IWGRP 00020 //組有寫權限 S_IXGRP 00010 //組有執行權限 S_IROTH 00004 //其餘人有讀權限 S_IWOTH 00002 //其餘人有寫權限 S_IXOTH 00001 //其餘人有可執行權限
opendir函數及readdir函數:socket
DIR * opendir(const char * name); //打開一個目錄 struct dirent * readdir(DIR *); //讀目錄,依次返回目錄的子項
dirent結構體:函數
struct dirent{ ino_t d_ino; //子項的i節點 off_t d_off; //節點的偏移量 unsigned short d_reclen;//長度 unsigned char d_type; //子項類型(經常使用) char d_name[256]; //子文件名(經常使用) };
①秒差形式,1970年1月1日0時0分0秒的秒數差,獲得的類型爲time_t;ui
②結構形式,tm結構體:spa
struct tm{ int tm_sec; //Second [0,60].包含閏秒 int tm_min; //Minutes [0,59]. int tm_hour; //Hour [0,23]. int tm_mday; //Day of month [1,31]. int tm_mon; //Month of year [0,11].(January = 0) int tm_year; //Year Since 1900. int tm_wday; //Day of week [0,6] (Sunday = 0). int tm_yday; //Day of year [0,365].包含閏年 int tm_isdat;//Daylight Savings flag }
計算機大多數狀況使用time_t,由於效率高。可是顯示時爲tm結構形式。localtime()函數能夠實現: time_t 到 tm 的轉換。time_t的指針作參數,返回值tm的指針。.net
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<time.h> 5 #include<unistd.h> 6 #include<sys/types.h> 7 #include<dirent.h> 8 #include<grp.h> 9 #include<pwd.h> 10 #include<errno.h> 11 #include<sys/stat.h> 12 #include<limits.h> 13 #include<assert.h> 14 15 int flag = 0; 16 //用於分析參數 17 void AnalPara(int argc,char *argv[],char *path) 18 { 19 int i = 0; 20 for(i = 1;i < argc; ++i) 21 { //若是argv[i]中第一個字符是'-',則判斷是l a i中的哪些 22 if(strncmp(argv[i],"-",1)==0) 23 { 24 //參數爲a時,把1賦值給flag,flag所在內存中第一個位置爲1 25 if(strstr(argv[i],"a") != NULL) 26 { 27 flag |= 1 << 0; ////-a參數顯示該隱藏文件 28 } 29 //參數爲l時,第二個位置爲1 30 if(strstr(argv[i],"l") != NULL) 31 { 32 flag |= 1 << 1; //-l參數顯示該文件的詳細信息 33 } 34 //參數爲i時,第三個位置爲1 35 if(strstr(argv[i],"i") != NULL) 36 { 37 flag |= 1 << 2; //-i參數顯示該文件的inode number 38 } 39 //位運算可以使用一個變量同時標記多個參數是否傳遞 40 } 41 //若是argv[i]中第一個字符不是'-',則判斷所給路徑是直接路徑仍是間接路徑 42 else 43 { 44 //直接路徑,copy到path字符數組中 45 if(strncmp(argv[i],"/",1) == 0) 46 { 47 strcpy(path,argv[i]); 48 } 49 //間接路徑,將當前路徑與所給路徑鏈接 50 else 51 { 52 strcat(path,"/"); 53 strcat(path,argv[i]); 54 } 55 } 56 } 57 } 58 //用於輸出文件名 59 void PrintfFileName(int mode,int uid,char *name) 60 { 61 //是目錄文件 62 if(S_ISDIR(mode)) 63 { 64 //文件名顯示爲藍色 65 printf("\33[1;34m%s\033[0m ",name); 66 } 67 //是普通文件 68 else if(S_ISREG(mode)) 69 { 70 if(mode & S_IXUSR||mode & S_IXGRP||mode & S_IXOTH) 71 { 72 if(uid==0) //屬主用戶,文件名顯示爲紅色 73 printf("\33[41;37m%s\033[0m ",name); 74 else //其餘用戶,文件名顯示爲綠色 75 printf("\33[1;32m%s\033[0m ",name); 76 } 77 else 78 { 79 printf("%s ",name); 80 } 81 } 82 else 83 { 84 printf("%s ",name); 85 } 86 } 87 //用於輸出文件詳細信息 88 void PrintMoreInfo(int mode,struct stat st) 89 { //文件權限判斷 90 char str[10] = {"----------"}; 91 92 if(S_ISDIR(mode)) str[0] = 'd'; 93 if(S_ISCHR(mode)) str[0] = 'c'; 94 if(S_ISBLK(mode)) str[0] = 'b'; 95 96 if(mode & S_IRUSR) str[1] = 'r'; 97 if(mode & S_IWUSR) str[2] = 'w'; 98 if(mode & S_IXUSR) str[3] = 'x'; 99 100 if(mode & S_IRGRP) str[4] = 'r'; 101 if(mode & S_IWGRP) str[5] = 'w'; 102 if(mode & S_IXGRP) str[6] = 'x'; 103 104 if(mode & S_IROTH) str[7] = 'r'; 105 if(mode & S_IWOTH) str[8] = 'w'; 106 if(mode & S_IXOTH) str[9] = 'x'; 107 108 int i = 0; 109 for(; i < 10; i++) 110 { 111 printf("%c",str[i]); 112 } 113 printf(". "); 114 printf("%ld ",st.st_nlink); 115 //輸出屬主 116 struct passwd *pd = getpwuid(st.st_uid); 117 assert(pd != NULL); 118 printf("%4s ",pd->pw_name); 119 //輸出組用戶 120 struct group *gp = getgrgid(st.st_gid); 121 assert(gp != NULL); 122 printf("%4s ",gp->gr_name); 123 //輸出文件大小 124 printf("%4ld ",st.st_size); 125 //輸出最近操做時間 126 struct tm * lchangetime = localtime(&(st.st_mtime)); 127 printf("%d %d %d:%d ",(lchangetime->tm_mon+1),lchangetime->tm_mday,lchangetime->tm_hour,lchangetime->tm_min); 128 } 129 130 int main(int argc,char *argv[]) 131 { 132 char path[128]={0}; 133 //獲取當前路徑 134 getcwd(path,127); 135 //參數分析函數 136 AnalPara(argc,argv,path); 137 //打開該目錄並創建一個目錄流 138 DIR *dir = opendir(path); 139 if(dir == NULL) 140 { 141 char *p = path + strlen(path); 142 while(*p != '/') 143 p--; 144 p++; 145 printf("ls:can not access %s:No such file or directory\n",p); 146 exit(0); 147 } 148 //須要使用dirent結構體中的文件名和文件的inode number 149 struct dirent *dr = NULL; 150 //調用readdir函數獲取該目錄中的目錄項 151 while((dr = readdir(dir)) != NULL) 152 { 153 //當文件名第一個字符是.時,爲隱藏文件,不輸出 154 if(((flag&1)==0) && (strncmp(dr->d_name,".",1) == 0)) 155 { 156 continue; 157 } 158 159 struct stat st; 160 char temp[128] = {0}; 161 strcpy(temp,path); 162 strcat(temp,"/"); 163 strcat(temp,dr->d_name); 164 stat(temp,&st); 165 //-li 166 if ((flag&2)==2) 167 { 168 //有參數i 169 if((flag&4)==4) 170 { 171 printf("%ld ",st.st_ino); 172 } 173 //有參數l 174 PrintMoreInfo(st.st_mode,st); 175 PrintfFileName(st.st_mode,st.st_uid,dr->d_name); 176 printf("\n"); 177 continue; 178 } 179 //-ai 180 if((flag&4)==4) 181 { 182 printf("%ld ",dr->d_ino); 183 PrintfFileName(st.st_mode,st.st_uid,dr->d_name); 184 continue; 185 } 186 //-a 187 PrintfFileName(st.st_mode,st.st_uid,dr->d_name); 188 } 189 if(argc == 1||(argc >1&&flag == 0)) 190 printf("\n"); 191 closedir(dir); 192 }
第一列爲文件/目錄的索引編號(inode number),若是是目錄,則使用dirent結構體中的d_ino獲取;若是是文件,則使用stat結構體中的st_ino獲取。
第二列爲文件的權限,第一位的-表示不一樣的文件類型(普通文件,管道文件)。後面九位分別表示,該文件的屬主,組用戶和其餘用戶的讀、寫、執行三種不一樣的權限。
第三列爲文件的硬連接數,若是是一個目錄,則第2字段表示該目錄所含子目錄的個數。使用stat結構體中的st_nlink獲取。
第四列爲屬主用戶,使用stat結構體中的st_uid獲取。
第五列爲組用戶,使用stat結構體中的st_gid獲取。
第六列爲文件所佔用的大小,以字節爲單位,若是是目錄文件,則表示該目錄的大小,而不是該目錄下全部文件的大小。使用stat結構體中的st_size獲取。
第七列爲最後修改時間,使用stat結構體中的st_mtime獲取。
第八列爲文件名,使用dirent結構體中的d_name獲取。