先看效果
Ubuntu 18.04 ZSH
ls
ls -a
ls -l
稍有不同
ls -al
稍有不同
代码实现
源码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<dirent.h>
#include<sys/types.h>
#include<pwd.h>
#include<grp.h>
#include<time.h>
#include<unistd.h>
#define CNT 256
#define COLOR_HL(a, b) "\033[1;" #b "m" a "\033[0m"
#define GREEN_HL(a) COLOR_HL(a,32)
#define BLUE_HL(a) COLOR_HL(a,34)
#define Type(a) _Generic((a),\
int : "%d", \
double : "%lf", \
float : "%f", \
long long : "%lld", \
const char* : "%s", \
char * : "%s" \
)
#define P(a, color) {\
char str_temp[100];\
sprintf(str_temp, color("%s"), Type(a));\
printf(str_temp, a);\
}
#define SWAP(a, b) {\
__typeof(a) temp = a;\
a = b;\
b = temp;\
}
typedef struct name_list{
char type;
char access[CNT];
int link_num;
char owner[CNT];
char group[CNT];
int size;
char time[CNT];
char name[CNT];
} name_list;
int file_name(DIR *fp, char *path, struct name_list name[CNT], int all_flag);
void str_sort(struct name_list name[CNT], int index[CNT], int cnt);
char *time_change(char *time);
void show(struct name_list name[CNT], int index[CNT], int cnt);
void show_l(struct name_list name[CNT], int index[CNT], int cnt);
void swap(struct name_list n1, struct name_list n2);
void get_access_permission(struct stat buf, char* res);
char get_file_type(struct stat buf);
int main(int argc, char *argv[]) {
DIR *fp;
struct name_list name[CNT];
int index[CNT];
int cnt, c;
int all_flag = 0, list_flag = 0;
char file_path[CNT] = "./";
while ((c = getopt(argc, argv, "al")) != -1) {
switch(c) {
case 'a':
all_flag = 1;break;
case 'l':
list_flag = 1;break;
default:
strcpy(file_path, optarg);
}
}
fp = opendir(file_path);
cnt = file_name(fp, file_path, name, all_flag);
for (int i = 0; i < cnt; i++){
index[i] = i;
}
str_sort(name, index, cnt);
if (list_flag == 1) {
show_l(name, index, cnt);
}
else {
show(name, index, cnt);
}
return 0;
}
void show_l(struct name_list name[CNT], int index[CNT], int cnt){
printf("%d\n", cnt);
for (int i = 0; i < cnt; i++) {
int temp = index[i];
printf("%c%s %3d %s %s %5d %s ", name[temp].type, name[temp].access, name[temp].link_num,
name[temp].owner, name[temp].group, name[temp].size, name[temp].time);
if (name[temp].type == 'd'){
P(name[temp].name, BLUE_HL);
printf("\n");
}
else if (name[temp].access[8] == 'x') {
P(name[temp].name, GREEN_HL);
printf("\n");
}
else {
printf("%s\n", name[temp].name);
}
}
}
void show(struct name_list name[CNT], int index[CNT], int cnt){
for (int i = 0; i < cnt; i++) {
int temp = index[i];
i && printf(" ");
if (name[temp].type == 'd'){
P(name[temp].name, BLUE_HL);
}
else if (name[temp].access[8] == 'x') {
P(name[temp].name, GREEN_HL);
}
else {
printf("%s", name[temp].name);
}
}
printf("\n");
}
int file_name(DIR *fp, char *path, struct name_list name[CNT], int all_flag) {
int cnt = 0;
struct dirent *p;
while ((p = readdir(fp)) != NULL) {
if ((strncmp(p->d_name, ".", 1) == 0 || strncmp(p->d_name, "..", 2) ==0) && !all_flag) {
continue;
}
strcat(name[cnt].name, p->d_name);
struct stat buf;
lstat(p->d_name, &buf);
get_access_permission(buf, name[cnt].access);
name[cnt].type = get_file_type(buf);
name[cnt].link_num = buf.st_nlink;
strcat(name[cnt].owner, getpwuid(buf.st_uid)->pw_name);
strcat(name[cnt].group, getgrgid(buf.st_gid)->gr_name);
struct tm *ptime;
name[cnt].size = buf.st_size;
ptime = localtime(&(buf.st_mtime));
sprintf(name[cnt].time, "%d-%d-%d %2d:%2d", ptime->tm_year + 1900, ptime->tm_mon, ptime->tm_mday,
ptime->tm_hour, ptime->tm_min);
cnt++;
}
closedir(fp);
return cnt;
}
void get_access_permission(struct stat buf, char* res){
strcat(res,(S_IRUSR & buf.st_mode) ? "r": "-");
strcat(res,(S_IWUSR & buf.st_mode) ? "w": "-");
strcat(res,(S_IXUSR & buf.st_mode) ? "x": "-");
strcat(res,(S_IRGRP & buf.st_mode) ? "r": "-");
strcat(res,(S_IWGRP & buf.st_mode) ? "w": "-");
strcat(res,(S_IXGRP & buf.st_mode) ? "x": "-");
strcat(res,(S_IROTH & buf.st_mode) ? "r": "-");
strcat(res,(S_IWOTH & buf.st_mode) ? "w": "-");
strcat(res,(S_IXOTH & buf.st_mode) ? "x": "-");
}
char get_file_type(struct stat buf){
if(S_ISREG(buf.st_mode)){
return '-';
}
else if(S_ISDIR(buf.st_mode)){
return 'd';
}
else if(S_ISCHR(buf.st_mode)){
return 'c';
}
else if(S_ISBLK(buf.st_mode)){
return 'b';
}
else if(S_ISFIFO(buf.st_mode)){
return 'p';
}
else if(S_ISLNK(buf.st_mode)){
return 'l';
}
else if(S_ISSOCK(buf.st_mode)){
return 's';
}
}
void str_sort(struct name_list name[CNT], int index[CNT], int cnt) {
for (int i = 1; i < cnt; i++){
for (int j = 0; j < cnt - i; j++){
if (strcmp(name[index[j]].name, name[index[j + 1]].name) > 0) {
SWAP(index[j], index[j + 1]);
}
}
}
}
生成可执行文件
gcc myls.c -o myls
cp myls /usr/bin/myls
|