歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

Linux下寫自己的ls命令

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

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;backgroundmhello\033[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的部分功能,後面還會繼續完成其余的功能!

Copyright © Linux教程網 All Rights Reserved