如何來寫自己的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遊戲引擎的朋友學會如何更好的寫遊戲指令碼,當然本文這緊緊是我這麼多年對遊戲開發的認知,你也可以有你自己的看法。首...