如何來寫自己的ls命令

2021-07-01 21:26:48 字數 3065 閱讀 4419

如何來寫自己的ls命令

王老師,華清遠見嵌入式學院講師。

很多實際證明,最好的學習方法是將相關的知識點應用到具體的例子中。這樣我們不僅知道了原理,也學會了怎麼應用。在學習檔案io時,我們可以嘗試來寫ls命令。所以在寫ls命令之前,我們必須要明確ls命令能做些什麼,然後才能知道要怎麼去寫ls命令。

其實ls的引數選項很多,大多也可以組合使用。我們必須明確實現自己的ls命令不是一步就到位的,要先學會怎樣去實現它的基本功能。在這裡,我以最簡單的

ls –l (特定的檔案)

作為例子裡給大家分析下如何去寫linux的命令。

我們觀察終端的列印資訊,怎樣才能按照特定的格式去輸出檔案的這些資訊?為了完成這個特定的功能我們要完成以下兩步:

1.如何獲取檔案資訊

2.如何按格式規則去輸出檔案資訊

下面我們來做進一步分析:

第一步,如何來獲取檔案資訊。 

在c庫中為我們提供了一組函式用來獲取檔案(普通檔案,目錄,管道,socket,字元,塊)的屬性。 

它們的函式原型 

#include

#include

#include

int stat(const char *path, struct stat *buf); /*提供檔案名字,獲取檔案對應屬性。*/

int fstat(int filedes, struct stat *buf); /*通過檔案描述符獲取檔案對應的屬性。*/

int lstat(const char *path, struct stat *buf);/* 連線檔案描述命,獲取檔案屬性。*/

這裡要指出的stat和lstat不同點在於對於鏈結檔案,stat顯示的是鏈結檔案指向的實際的檔案的屬性,也就是返回該符號鏈結引用檔案的資訊,而lstat顯示的是由返回該符號鏈結的有關資訊

引數: path: 

檔案路徑名。 filedes:檔案描述詞。 

buf:是以下結構體的指標,用來描述檔案對應的屬性 

struct stat 

;函式實現如下:

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc,char *argv)

int i;

struct stat buf;

char out[500];

char *p;

if (lstat(argv[1],&buf)==-1)

}這個時候我們已經得到了buf這個結構體,從這個結構體中很容易就能寫出以下資訊,實現起來比較容易:

//連線數 

printf(" %d",buf.st_nlink); 

// 使用者id

struct passwd *user;

user=getpwuid(buf.st_uid);

printf(" %s",user->pw_name);

//組id

struct group *group;

group=getgrgid(buf.st_gid);

printf(" %s",group->gr_name);

//大小 

printf(" %d ",buf.st_size);

//時間 

struct tm *t;

t=localtime(&buf.st_ctime);

printf(" %d-%d-%d %d:%d",t->tm_year+1900,

t->tm_mon+1,

t->tm_mday,

t->tm_hour,

t->tm_sec);

printf(" %s",argv[1]);

到目前為止,還剩下檔案型別,以及對於使用者,組,其他使用者的讀寫許可權沒有解析出來,其實我們所需要的資訊已經包含在buf的st_mode中,只要對這個返回的st_mode進行解析就可以得到我們所需要的資訊。

先來看看檔案的型別,如何對檔案型別來判斷呢?可以使用掩碼來解碼得到檔案的型別。在中有以下定義:

#define s_ifmt 0170000

#define s_ifreg 0100000

#define s_ifdir 0040000

#define s_ifblk 0060000

....

我們如何要判斷檔案型別是否是普通檔案,可以寫如下**: 

if( (info.st_mode & 0170000) == 0100000)

printf("this is a regular file");

當然我們也可採取中定義的巨集來實現 

#define s_isfifo(m) ((m) &(0170000) == (0010000))

#define s_isreg(m) ( (m) & (0170000) == 0100000))

....

所以我們也可以寫如下**:

if( s_isdir(info.st_mode) )

printf("this is a regular file");

現在繼續補充剛剛沒有寫完的程式:

if (s_isreg(buf.st_mode)) p="-";

else if (s_isdir(buf.st_mode)) p="r";

else if (s_ischr(buf.st_mode)) p="c";

else if (s_isblk(buf.st_mode)) p="b";

else if (s_isfifo(buf.st_mode)) p="f";

else if (s_islnk(buf.st_mode)) p="l";

else if (s_issock(buf.st_mode)) p="s";

還剩下檔案對不同使用者的許可權的描述怎麼實現,同理用以上的方式來實現。

int n;

for(n=8;n>=0;n--)

{if(buf.st_mode&(1這樣將這四段寫在一起,就完成了實現ls –l 特定的檔案的功能。

實現自己的ls命令

估計每個使用過 linux系統的人都知道 ls是啥吧。也相信大家都對 ls的簡單命令爛熟於心了吧,這裡就不想再贅述了,直接進入正題吧。裡面會有許多注釋,相信的家一定能看懂的。說明 此 我在kail linux下編譯無任何錯誤,執行也基本無bug,相信大家在一般linux下執行也無問題。include...

程式設計實踐 實現自己的ls命令

函式功能 處理傳遞過來的路徑資訊,判斷檔案型別。函式功能 獲取檔案資訊 函式功能 獲取目錄資訊 函式功能 排序 函式功能 獲取檔案屬性並列印 函式功能 輸出檔名 函式功能 初始化鍊錶 函式功能 獲取最早插入的元素並刪除,判空 函式功能 插入新元素 函式功能 資訊輸出 引數處理部分自己開始沒有想出來,...

Unity3D之遊戲架構指令碼該如何來寫

這篇文章主要想大家說明一下我在unity3d遊戲開發中是如何寫遊戲指令碼的,對於unity3d這套遊戲引擎來說入門極快,可是要想做好卻非常的難。這篇文章的目的是讓哪些已經上手unity3d遊戲引擎的朋友學會如何更好的寫遊戲指令碼,當然本文這緊緊是我這麼多年對遊戲開發的認知,你也可以有你自己的看法。首...