歡迎您光臨本站 註冊首頁

寫自己的ls命令

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

作者:曹忠明,華清遠見嵌入式學院講師.

ls命令是linux下最常用的命令之一,它的使用很簡單,可是功能卻很多,有很多的參數,這裡我們就自己寫一個ls命令,實現ls基本的功能.在這之前我們先介紹幾個在實現ls過程中使用的函數.

stat/lstat函數

這兩個函數功能基本相同,都是獲得文件的屬性,區別在於如果文件是符號鏈接stat返回的是符號鏈接指向文件的屬性,而lstat返回的是符號鏈接本身的屬性.

函數原型:

int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);

path為文件路徑,buf為返回的狀態,類型為struct stat,結構體內容為:

struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */


time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};

這個結構體中成員st_mode用來表示文件的類型和文件的許可權,它的定義如下:

S_IFMT 0170000 bit mask for the file type bit fields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission

我們可以通過下面宏來判斷文件的類型

S_ISREG(m) is it a regular file?
S_ISDIR(m) directory?
S_ISCHR(m) character device?
S_ISBLK(m) block device?
S_ISFIFO(m) FIFO (named pipe)?
S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.)
S_ISSOCK(m) socket? (Not in POSIX.1-1996.)

接著我們就實現ls的第一步:獲得文件的屬性


這個例子只能實現查看一個特定文件的屬性,而ls實現的功能是如果是文件則顯示文件屬性,如果是目錄則顯示目錄中各個文件的屬性.
這些功能需要的函數為:

opendir/readdir函數用來獲取目錄項

原型:

DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
struct dirent描述目錄中每一項的內容
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported by all file system types */
char d_name[256]; /* filename */
};

getopt用來實現命令選項功能:

原型:

int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

readlink讀取符號鏈接內容:

原型:

ssize_t readlink(const char *path, char *buf, size_t bufsiz);


path為符號鏈接路徑
buf為符號鏈接內容
bufsize為要獲得內容長度
文件按照屬性顯示顏色
033[mode;foreground;backgroundmhello33[0m

mode為顯示模式:
0、1、22、4、24、5、25、7、27,分別表示設定顏色、黑體、非黑體、下畫線、非下畫線、閃爍、非閃爍、翻轉、非翻轉.

foreground為前景顏色:
30 (黑色)、31 (紅色)、32 (綠色)、33 (黃色)、34 (藍色)、35 ( 紫紅色)、36 (青色)和37 (白色)

background為背景顏色:
40 (黑色)、41 (紅色)、42 (綠色)、43 (黃色)、44 (藍色)、45 ( 紫紅色)、46 (青色)和47 (白色)

實現如下:








結果:

這裡只實現了ls的部分功能,後面還會繼續完成其餘的功能!

嵌入式及3G相關資源及學習請點擊:嵌入式開發視頻 android開發視頻 android培訓 3G培訓 QT培訓 QT開發視頻 物聯網培訓 物聯網技術視頻 嵌入式學習


[火星人 ] 寫自己的ls命令已經有495次圍觀

http://coctec.com/docs/linux/show-post-49221.html