Linux下的ls命令詳解以及C語言實現
一、眾所周知,ls是linux下最常用的命令之一,使用起來也相當的快捷與方便,ls 命令將每個由 Directory 引數指定的目錄或者每個由 File 引數指定的名稱寫到標準輸出,以及您所要求的和標誌一起的其它資訊。如果不指定 File 或 Directory 引數, ls 命令顯示當前目錄的內容。
使用語法如下:
ls (options) (引數)
1、options即為選項,常見的選項有如下…
-a:顯示所有檔案及目錄(ls內定將檔案名或目錄名稱為“.”的視為影藏,不會列出);
-A:顯示除影藏檔案“.”和“..”以外的所有檔案列表;
-F:在每個輸出項後追加檔案的型別識別符號,具體含義:“*”表示具有可執行許可權的普通檔案,“/”表示目錄,“@”表示符號連結,“|”表示命令管道FIFO,“=”表示sockets套接字。當檔案為普通檔案時,不輸出任何識別符號;
-b:將檔案中的不可輸出的字元以反斜線“”加字元編碼的方式輸出;
-f:此引數的效果和同時指定“aU”引數相同,並關閉“lst”引數的效果;
-k:以KB(千位元組)為單位顯示檔案大小;
-l:以長格式顯示目錄下的內容列表。輸出的資訊從左到右依次包括檔名,檔案型別、許可權模式、硬連線數、所有者、組、檔案大小和檔案的最後修改時間等;
-r:以檔名反序排列並輸出目錄內容列表;
-s:顯示檔案和目錄的大小,以區塊為單位;
-t:用檔案和目錄的更改時間排序;
-L:如果遇到性質為符號連結的檔案或目錄,直接列出該連結所指向的原始檔案或目錄;
-R:遞迴處理,將指定目錄下的所有檔案及子目錄一併處理;
注:選項可以多個進行組合使用,具體可實踐檢視效果。
2、引數
引數為要顯示的路徑或檔案,如不指定則為當前路徑。
二、運用C語言實現(ls -l path)
1、在shell中鍵入:ls -l , 檢視效果如下…
2、以下為C程式碼實現
/*
*實現ls -l的shell命令
*/
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<dirent.h>
#include<grp.h>
#include<pwd.h>
#define NAME_SIZE 20
struct fnode
{
struct fnode *next ; //下一個成員
char name[NAME_SIZE] ; //當前成員檔名
} ;
struct fnode* insert_list(struct fnode *node , struct fnode *linklist) ; //將節點插入連結串列中
void output_info(struct fnode *head) ; //輸出檔案資訊
void output_type_perm(mode_t mode) ; //列出檔案的許可權和型別字元
void output_user_group(uid_t uid , gid_t gid) ; //列出使用者及使用者資訊
void output_mtime(time_t mytime) ; //列出各檔案基本資訊
void myfree(struct fnode *linklist) ; //釋放記憶體
int main(int argc , char* argv[])
{
if(argc < 2)
{
printf("usage : %s dir_name \n" , argv[0]) ;
exit(EXIT_FAILURE) ;
}
int i ;
for(i = 1 ; i < argc ; i++)
{
struct fnode *linklist = NULL ;
struct stat stat_info ;
if(stat(argv[i] , &stat_info) == -1)
{
perror("stat") ;
exit(EXIT_FAILURE) ;
}
printf("argv[i] is : %s \n" , argv[i]) ;
if(S_ISREG(stat_info.st_mode)) //普通檔案
{
printf("It is a normal file\n") ;
struct fnode *temp = (struct fnode*) malloc(sizeof(struct fnode)) ; //為當前檔案結構申請記憶體空間
if(temp == NULL)
{
perror("malloc error") ;
exit(EXIT_FAILURE) ;
}
temp->next = NULL ;
//將當前檔名拷貝到temp->name中
memset(temp->name , '\0' , NAME_SIZE) ;
memcpy(temp->name , argv[i] , strlen(argv[i])) ;
linklist = insert_list(temp , linklist) ; //將該檔案插入linklist中
output_info(linklist) ; //輸出檔案的所有資訊
}
else if(S_ISDIR(stat_info.st_mode)) //是否是路徑
{
printf("It is a dir \n") ;
char buf[NAME_SIZE] ;
getcwd(buf , 128) ; //獲取當前工作路徑並將其拷貝到buf中
DIR *dirp = NULL ;
dirp = opendir(argv[i]) ; //開啟當前路徑
if(dirp == NULL)
{
perror("open dir") ;
exit(EXIT_FAILURE) ;
}
struct dirent *entp = NULL ;
while(entp = readdir(dirp))
{
struct fnode *temp = (struct fnode *)malloc(sizeof(struct fnode)) ;
if(temp == NULL)
{
perror("malloc") ;
exit(EXIT_FAILURE) ;
}
temp->next = NULL ;
memset(temp->name , '\0' , NAME_SIZE) ;
memcpy(temp->name , entp->d_name , strlen(entp->d_name)) ;
linklist = insert_list(temp , linklist) ;
}
chdir(argv[i]) ; //改變當前路徑
close(dirp) ;
output_info(linklist) ;
chdir(buf) ;
}
myfree(linklist) ;
}
return 0 ;
}
void output_type_perm(mode_t mode)
{
char type[7] = {'p' , 'c' , 'd' , 'b' , '-' , 'l' , 's'} ;
int index = ((mode >> 12) & 0xF) / 2 ;
printf("%c" , type[index]) ;
char *perm[8] = {"---" , "--x" , "-w-" , "-wx" , "r--" , "r-x" , "rw-" , "rwx"} ;
printf("%s" , perm[mode >> 6 & 07]) ;
printf("%s" , perm[mode >> 3 & 07]) ;
printf("%s" , perm[mode >> 0 & 07]) ;
}
void output_user_group(uid_t uid , gid_t gid)
{
struct passwd *user ;
user = getpwuid(uid) ;
printf(" %s" , user->pw_name) ;
struct group *group ;
group = getgrgid(gid) ;
printf(" %s" , group->gr_name) ;
}
void output_mtime(time_t mytime)
{
char buf[256] ;
memset(buf , '\0' , 256) ;
ctime_r(&mytime , buf) ;
buf[strlen(buf) - 1] = '\0' ;
printf(" %s" , buf) ;
}
void output_info(struct fnode *head)
{
struct fnode *temp = head ;
while(temp != NULL)
{
struct stat mystat ;
if(stat(temp->name , &mystat) == -1)
{
perror("stat") ;
exit(EXIT_FAILURE) ;
}
output_type_perm(mystat.st_mode) ;
printf(" %4d" , mystat.st_mode) ;
output_user_group(mystat.st_uid , mystat.st_gid) ;
printf(" %8ld" , mystat.st_size) ;
output_mtime(mystat.st_mtime) ;
printf(" %s\n" , temp->name) ;
temp = temp->next ;
}
}
struct fnode * insert_list(struct fnode* temp , struct fnode * linklist)
{
if(linklist == NULL)
{
linklist = temp ;
}
else
{
struct fnode *node ;
node = linklist ;
while(node->next != NULL)
{
node = node->next ;
}
node->next = temp ;
}
return linklist ;
}
void myfree(struct fnode *linklist)
{
struct fnode *temp ;
temp = linklist ;
while(temp != NULL)
{
temp = linklist->next ;
free(linklist) ;
linklist = temp ;
}
}
執行檢視效果…
其中的warning一直無解,明明將標頭檔案匯入,但總是提示函式未加宣告,但是不影響執行結果,如果有大神,還請不吝賜教…