2019.03.15王苛震——myls

本文详细介绍了一个自制的ls命令实现,包括-l、-a、-i、-h等选项的功能,通过C语言编程实现文件和目录的详细信息展示、隐藏文件显示、inode号显示及人性化文件大小显示。
  1 /*
  2  1.尝试实现ls命令的功能 加选项-l -a -i -h
  3  */
  4 #include <stdio.h>
  5 #include <sys/types.h>
  6 #include <sys/stat.h>
  7 #include <unistd.h>
  8 #include <errno.h>
  9 #include <time.h>
 10 #include <string.h>
 11 #include <stdlib.h>
 12 #include <dirent.h>
 13 #include <pwd.h>
 14 #include <grp.h>
 15 
 16 #define        MAX        1024
 17 
 18 static int myls_l(char *optarg);
 19 static void ls_all(char *path);
 20 static int myls_a(char *path);
 21 static int is_dir(char *path);
 22 static void myls_i(char *path);
 23 static void myls_i_notdir(char *path);
 24 static int myls_h(char *path);
 25 
 26 int main(int argc, char *argv[])
 27 {
 28     int c;
 29     char *str = "-l:a:i:h:";
 30     if (argc < 2)
 31         return -1;
 32     
 33     while (1) {
 34         if ((c = getopt(argc, argv, str)) == -1)
 35             break;
 36         switch (c) {
 37             case 'l':
 38                 is_dir(optarg) ? ls_all(optarg) : myls_l(optarg);
 39                 break;
 40             case 'a':
 41                 is_dir(optarg) ? myls_a(optarg) : puts(optarg);
 42                 break;
 43             case 'i':
 44                 is_dir(optarg) ? myls_i(optarg) : myls_i_notdir(optarg);
 45                 break;
 46             case 'h':
 47                 is_dir(optarg) ? myls_h(optarg) : puts(optarg);
 48                 break;
 49             case '?':
 50                 printf("输入选项错误\n");
 51                 break;
 52             case 1:
 53                 printf("错误参数选项%s\n", argv[optind-1]);
 54                 break;
 55             default:
 56                 break;
 57         }
 58     }
 59 
 60     return 0;
 61 }
 62 
 63 // 单文件显示详细信息 相当于ls -l +文件名
 64 static int myls_l(char *optarg)
 65 {
 66     struct stat buf;
 67 
 68     if (stat(optarg, &buf) == -1) {
 69         perror("STAT()");
 70         return -1;
 71     }
 72     // 文件类型
 73     if (S_ISREG(buf.st_mode))
 74         putchar('-');
 75     if (S_ISDIR(buf.st_mode))
 76         putchar('d');
 77     if (S_ISCHR(buf.st_mode))
 78         putchar('c');
 79     if (S_ISBLK(buf.st_mode))
 80         putchar('b');
 81     if (S_ISFIFO(buf.st_mode))
 82         putchar('p');
 83     if ((buf.st_mode & S_IFMT) == S_IFSOCK)
 84         putchar('s');
 85     if ((buf.st_mode & S_IFMT) == S_IFLNK)
 86         putchar('l');
 87     // 权限
 88     if (buf.st_mode & S_IRUSR)
 89         putchar('r');
 90     else
 91         putchar('-');
 92     if (buf.st_mode & S_IWUSR)
 93         putchar('w');
 94     else
 95         putchar('-');
 96     if (buf.st_mode & S_IXUSR) {
 97         if (buf.st_mode & S_ISUID) {
 98             putchar('s');
 99         } else {
100             putchar('x');
101         }
102     }
103     else
104         putchar('-');
105     if (buf.st_mode & S_IRGRP)
106         putchar('r');
107     else
108         putchar('-');
109     if (buf.st_mode & S_IWGRP)
110         putchar('w');
111     else
112         putchar('-');
113     if (buf.st_mode & S_IXGRP) {
114         if (buf.st_mode & S_ISGID) {
115             putchar('s');
116         } else {
117             putchar('x');
118         }
119     }
120     else
121         putchar('-');
122     if (buf.st_mode & S_IROTH)
123         putchar('r');
124     else
125         putchar('-');
126     if (buf.st_mode & S_IWOTH)
127         putchar('w');
128     else
129         putchar('-');
130     if (buf.st_mode & S_IXOTH) {
131         if (buf.st_mode & S_ISVTX) {
132             putchar('t');
133         } else {
134             putchar('x');
135         }
136     }
137     else
138         putchar('-');
139     // 硬链接
140     printf(" %zu ", buf.st_nlink);
141     // 拥有者
142     struct passwd *pwd = NULL;
143     pwd = getpwuid(buf.st_uid);
144     printf("%s ", pwd->pw_name);
145     // 所属组
146     struct group *grp = NULL;
147     grp = getgrgid(buf.st_gid);
148     printf("%s ", grp->gr_name);
149     // 文件字节大小
150     printf("%zu ", buf.st_size);
151     // 最后更改文件时间
152     struct tm *tmp = NULL;
153     char s[MAX] = {};
154     tmp = localtime(&(buf.st_mtim.tv_sec));
155     strftime(s, MAX, "%m月  %d %H:%M ", tmp);
156     printf("%s ", s);
157     // 文件名
158     char *ptr = NULL;
159     if ((ptr = strrchr(optarg, '/')) != NULL) {
160         printf("%s", ptr+1);
161     } else {
162         printf("%s", optarg);
163     }
164 
165     putchar('\n');
166 
167     return 0;
168 }
169 
170 // 判断该文件名第一个字符是否为隐藏文件和 . .. .asd
171 static int is_hidden(char *str)
172 {
173     if (str[0] == '.') {
174         return 1;        // 是隐藏文件返回1
175     }
176         return 0;
177 }
178 
179 // 相当于 ls -l +目录的路径
180 static void ls_all(char *path)
181 {
182     DIR *dp = NULL;
183     char str[MAX] = {};
184     struct dirent *ret_dir = NULL;
185     dp = opendir(path);
186 
187     while (1) {
188         memset(str, '\0', MAX);
189         strcpy(str, path);
190         strcat(str, "/");
191         if ((ret_dir = readdir(dp)) != NULL) {
192             if (is_hidden(ret_dir->d_name))        //排除隐藏文件
193                 continue;
194             strcat(str, ret_dir->d_name);        //完整路径
195             myls_l(str);                        //调用函数
196         } else {        // 目录读取完毕
197             break;
198         }
199     }
200     closedir(dp);
201 }
202 
203 // 判断是文件还是目录    是目录返回1 不是返回0
204 static int is_dir(char *path)
205 {
206     struct stat buf;
207     lstat(path, &buf);
208     if (!S_ISDIR(buf.st_mode)) {
209         return 0;
210     } else
211         return 1;
212 }
213 
214 // 相当于 ls -a +目录的路径        (当前目录下所以文件包含隐藏文件)
215 static int myls_a(char *path)
216 {
217     DIR *dp = NULL;
218     struct dirent *ptr = NULL;
219 
220     dp = opendir(path);
221     if (dp == NULL) {
222         perror("OPENDIR()");
223         return -1;
224     }
225     while (1) {
226         ptr = readdir(dp);    //返回值为结构体类型指针
227         if (ptr == NULL) {
228             if (errno) {
229                 perror("READDIR()");
230                 closedir(dp);
231                 return -1;
232             }
233             break;
234         }
235         printf("%s\n", ptr->d_name);
236     }
237 
238     closedir(dp);
239     return 0;
240 }
241 
242 // 相当于 ls -i +目录    显示当前目录下所有文件的inode号 (不包含隐藏)
243 static void myls_i(char *path)
244 {
245     DIR *dp = NULL;
246     struct dirent *entry = NULL;
247     dp = opendir(path);
248     while (1) {
249         if ((entry = readdir(dp)) == NULL)
250             break;
251         if (is_hidden(entry->d_name)) {    //隐藏文件
252             continue;
253         }
254         printf("%zu %s\n", entry->d_ino, entry->d_name);
255     }
256 }
257 
258 // 相当于 ls -i +文件
259 static void myls_i_notdir(char *path)
260 {
261     struct stat buf;
262     stat(path, &buf);
263     printf("%zu %s\n", buf.st_ino, path);
264 }
265 
266 // 相当于 ls -h +目录    本目录下所有文件(不包含隐藏)
267 static int myls_h(char *path)
268 {
269     DIR *dp = NULL;
270     struct dirent *ptr = NULL;
271 
272     dp = opendir(path);
273     if (dp == NULL) {
274         perror("OPENDIR()");
275         return -1;
276     }
277     while (1) {
278         ptr = readdir(dp);    //返回值为结构体类型指针
279         if (ptr == NULL) {
280             if (errno) {
281                 perror("READDIR()");
282                 closedir(dp);
283                 return -1;
284             }
285             break;
286         }
287         if (is_hidden(ptr->d_name)) {
288             continue;
289         }
290         printf("%s\n", ptr->d_name);
291     }
292 
293     closedir(dp);
294     return 0;
295 }

 

转载于:https://www.cnblogs.com/ymfqq/p/10538537.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值