主頁 > 作業系統 > 作業系統第四次實驗報告——檔案系統之使用LinuxAPI實作ls -lai命令

作業系統第四次實驗報告——檔案系統之使用LinuxAPI實作ls -lai命令

2020-09-20 15:33:35 作業系統

0 個人資訊

  • 張櫻姿
  • 201821121038
  • 計算1812

1 實驗目的

  • 通過編程進一步了解檔案系統,

2 實驗內容

  • 在服務器上用Vim撰寫一個程式:實作Linux系統命令ls -lai的功能
  • 給出運行結果截圖,對于每一列是如何獲取的,結合源代碼做解釋

3 實驗報告

  3.1 ls -lai簡介

ls -l   #以長格式顯示目錄下的內容串列,輸出的資訊從左到右依次包括檔案名,檔案型別、權限模式、硬連接數、所有者、組、檔案大小和檔案的最后修改時間等
ls -a   #顯示所有檔案及目錄(ls內定將檔案名或目錄名稱為“.”的視為影藏,不會列出)
ls -i   #顯示檔案索引節點號(inode number),一個索引節點代表一個檔案

  3.2 實作程序

    3.2.1 獲取檔案資訊的函式及檔案資訊結構體

     stat函式:

#include<sys/stat.h>
int stat(const char * path,struct stat * buf); /*將path引數(檔案或目錄)的檔案資訊寫到buf中,buf為傳出引數*/

     stat結構體:

struct stat{
    dev_t st_dev;            //設備id號(無需用到)
    ino_t st_ino;            //索引節點號
    mode_t st_mode;          //權限與檔案型別
    nlink_t st_nlink;        //硬鏈接數
    uid_t st_uid;            //用戶id
    ggid_t st_gid;           //所在組id
    dev_t st_rdev;           //設備id,對于特殊檔案才有(無需用到)
    off_t st_size;           //大小,較為常用
    blksize_t st_blocks;     //檔案系統I/O的塊大小(無需用到)
    blkcnt_t st_blksize;     //分配的512B(扇區)塊數(無需用到)
    time_t st_atime;         //最后的訪問時間(無需用到)
    time_t st_mtime;         //最后的修改時間,較為常用
    time_t st_ctime;         //最后的狀態改變時間(無需用到)
}                    

       因此,需對上述相應欄位格式化處理,

    3.2.2 mode權限與型別判斷

     判斷檔案型別的宏函式:

    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.)       //判斷是否是SOCKET檔案

     檔案權限宏變數:

        S_IRUSR     00400     //用戶有讀權限
        S_IWUSR     00200     //用戶有寫權限
        S_IXUSR     00100     //用戶有執行權限
        S_IRGRP     00040     //組有讀權限
        S_IWGRP     00020     //組有寫權限
        S_IXGRP     00010     //組有執行權限
        S_IROTH     00004     //其他人有讀權限
        S_IWOTH     00002     //其他人有寫權限
        S_IXOTH     00001     //其他人有可執行權限       

    3.2.3 目錄操作函式及目錄資訊結構體

     opendir函式及readdir函式:

DIR * opendir(const char * name);    //打開一個目錄
struct dirent * readdir(DIR *);      //讀目錄,依次回傳目錄的子項

      dirent結構體:

struct dirent{
    ino_t d_ino;    //子項的i節點
    off_t d_off;    //節點的偏移量
    unsigned short d_reclen;//長度
    unsigned char d_type;   //子項型別(常用)
    char d_name[256];       //子檔案名(常用)
};

    3.2.4 表示時間的方式

     ①秒差形式,1970年1月1日0時0分0秒的秒數差,得到的型別為time_t;

    ②結構形式,tm結構體:

struct tm{
    int tm_sec;  //Second [0,60].包含閏秒
    int tm_min;  //Minutes [0,59].
    int tm_hour; //Hour [0,23].
    int tm_mday; //Day of month [1,31].
    int tm_mon;  //Month of year [0,11].(January = 0)
    int tm_year; //Year Since 1900.
    int tm_wday; //Day of week [0,6] (Sunday = 0).
    int tm_yday; //Day of year [0,365].包含閏年
    int tm_isdat;//Daylight Savings flag
}

    計算機大多數情況使用time_t,因為效率高,但是顯示時為tm結構形式,localtime()函式可以實作: time_t 到 tm 的轉換,time_t的指標做引數,回傳值tm的指標,

  3.3 源代碼

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<time.h>
  5 #include<unistd.h>
  6 #include<sys/types.h>
  7 #include<dirent.h>
  8 #include<grp.h>
  9 #include<pwd.h>
 10 #include<errno.h>
 11 #include<sys/stat.h>
 12 #include<limits.h>
 13 #include<assert.h>
 14 
 15 int flag = 0;
 16 //用于分析引數
 17 void AnalPara(int argc,char *argv[],char *path)
 18 {
 19     int i = 0;
 20     for(i = 1;i < argc; ++i)
 21     {    //如果argv[i]中第一個字符是'-',則判斷是l a i中的哪些
 22         if(strncmp(argv[i],"-",1)==0)
 23         {
 24             //引數為a時,把1賦值給flag,flag所在記憶體中第一個位置為1
 25             if(strstr(argv[i],"a") != NULL)
 26             {
 27                 flag |= 1 << 0; ////-a引數顯示該隱藏檔案
 28             }
 29             //引數為l時,第二個位置為1
 30             if(strstr(argv[i],"l") != NULL)
 31             {
 32                 flag |= 1 << 1;    //-l引數顯示該檔案的詳細資訊
 33             }
 34             //引數為i時,第三個位置為1
 35             if(strstr(argv[i],"i") != NULL)
 36             {
 37                 flag |= 1 << 2;    //-i引數顯示該檔案的inode number
 38             }
 39             //位運算可使用一個變數同時標記多個引數是否傳遞
 40         }
 41         //如果argv[i]中第一個字符不是'-',則判斷所給路徑是直接路徑還是間接路徑
 42         else
 43         {
 44             //直接路徑,copy到path字符陣列中
 45             if(strncmp(argv[i],"/",1) == 0)
 46             {
 47                 strcpy(path,argv[i]);
 48             }
 49             //間接路徑,將當前路徑與所給路徑連接
 50             else
 51             {
 52                 strcat(path,"/");
 53                 strcat(path,argv[i]);
 54             }
 55         }
 56     }
 57 }
 58 //用于輸出檔案名
 59 void PrintfFileName(int mode,int uid,char *name)
 60 {
 61     //是目錄檔案
 62     if(S_ISDIR(mode))
 63     {
 64         //檔案名顯示為藍色
 65         printf("\33[1;34m%s\033[0m ",name);
 66     }
 67     //是普通檔案
 68     else if(S_ISREG(mode))
 69     {
 70         if(mode & S_IXUSR||mode & S_IXGRP||mode & S_IXOTH)
 71         {
 72             if(uid==0) //屬主用戶,檔案名顯示為紅色
 73                 printf("\33[41;37m%s\033[0m ",name);
 74             else       //其他用戶,檔案名顯示為綠色
 75                 printf("\33[1;32m%s\033[0m ",name);
 76         }
 77         else
 78         {
 79             printf("%s ",name);
 80         }
 81     }
 82     else
 83     {
 84         printf("%s ",name);
 85     }
 86 }
 87 //用于輸出檔案詳細資訊
 88 void PrintMoreInfo(int mode,struct stat st)
 89 {    //檔案權限判斷
 90     char str[10] = {"----------"};
 91 
 92     if(S_ISDIR(mode)) str[0] = 'd';
 93     if(S_ISCHR(mode)) str[0] = 'c';
 94     if(S_ISBLK(mode)) str[0] = 'b';
 95 
 96     if(mode & S_IRUSR) str[1] = 'r';
 97     if(mode & S_IWUSR) str[2] = 'w';
 98     if(mode & S_IXUSR) str[3] = 'x';
 99 
100     if(mode & S_IRGRP) str[4] = 'r';
101     if(mode & S_IWGRP) str[5] = 'w';
102     if(mode & S_IXGRP) str[6] = 'x';
103 
104     if(mode & S_IROTH) str[7] = 'r';
105     if(mode & S_IWOTH) str[8] = 'w';
106     if(mode & S_IXOTH) str[9] = 'x';
107 
108     int i = 0;
109     for(; i < 10; i++)
110     {
111         printf("%c",str[i]);
112     }
113     printf(". ");
114     printf("%ld ",st.st_nlink);
115     //輸出屬主
116     struct passwd *pd = getpwuid(st.st_uid);
117     assert(pd != NULL);
118     printf("%4s ",pd->pw_name);
119     //輸出組用戶
120     struct group *gp = getgrgid(st.st_gid);
121     assert(gp != NULL);
122     printf("%4s ",gp->gr_name);
123     //輸出檔案大小
124     printf("%4ld ",st.st_size);
125     //輸出最近操作時間
126     struct tm * lchangetime = localtime(&(st.st_mtime));
127     printf("%d %d %d:%d ",(lchangetime->tm_mon+1),lchangetime->tm_mday,lchangetime->tm_hour,lchangetime->tm_min);
128 }
129 
130 int main(int argc,char *argv[])
131 {
132     char path[128]={0};
133     //獲取當前路徑
134     getcwd(path,127);
135     //引數分析函式
136     AnalPara(argc,argv,path);
137     //打開該目錄并建立一個目錄流
138     DIR *dir = opendir(path);
139     if(dir == NULL)
140     {
141         char *p = path + strlen(path);
142         while(*p != '/')
143             p--;
144         p++;
145         printf("ls:can not access %s:No such file or directory\n",p);
146         exit(0);
147     }
148     //需要使用dirent結構體中的檔案名和檔案的inode number
149     struct dirent *dr = NULL;
150     //呼叫readdir函式獲取該目錄中的目錄項
151     while((dr = readdir(dir)) != NULL)
152     {    
153         //當檔案名第一個字符是.時,為隱藏檔案,不輸出
154         if(((flag&1)==0) && (strncmp(dr->d_name,".",1) == 0))
155         {
156             continue;
157         }
158 
159         struct stat st;
160         char temp[128] = {0};
161         strcpy(temp,path);
162         strcat(temp,"/");
163         strcat(temp,dr->d_name);
164         stat(temp,&st);
165         //-li
166         if ((flag&2)==2)
167         {
168             //有引數i
169             if((flag&4)==4)
170             {
171                 printf("%ld  ",st.st_ino);
172             }
173             //有引數l
174             PrintMoreInfo(st.st_mode,st);
175             PrintfFileName(st.st_mode,st.st_uid,dr->d_name);
176             printf("\n");
177             continue;
178         }
179         //-ai
180         if((flag&4)==4)
181         {
182             printf("%ld  ",dr->d_ino);
183             PrintfFileName(st.st_mode,st.st_uid,dr->d_name);
184             continue;
185         }
186         //-a
187         PrintfFileName(st.st_mode,st.st_uid,dr->d_name);
188     }
189     if(argc == 1||(argc >1&&flag == 0))
190         printf("\n");
191     closedir(dir);
192 }

  3.4 分析結果

    3.4.1 ls -lai運行結果:

 

 

     3.4.2 ./myls -lai運行結果:

     3.4.3 分析輸出格式:

    第一列為檔案/目錄的索引編號(inode number),如果是目錄,則使用dirent結構體中的d_ino獲取;如果是檔案,則使用stat結構體中的st_ino獲取,

    第二列為檔案的權限,第一位的-表示不同的檔案型別(普通檔案,管道檔案),后面九位分別表示,該檔案的屬主,組用戶和其他用戶的讀、寫、執行三種不同的權限,

    第三列為檔案的硬鏈接數,如果是一個目錄,則第2欄位表示該目錄所含子目錄的個數,使用stat結構體中的st_nlink獲取,

    第四列為屬主用戶,使用stat結構體中的st_uid獲取,

    第五列為組用戶,使用stat結構體中的st_gid獲取,

    第六列為檔案所占用的大小,以位元組為單位,如果是目錄檔案,則表示該目錄的大小,而不是該目錄下所有檔案的大小,使用stat結構體中的st_size獲取,

    第七列為最后修改時間,使用stat結構體中的st_mtime獲取,

    第八列為檔案名,使用dirent結構體中的d_name獲取,

4 References

  • https://blog.csdn.net/apollon_krj/article/details/54710135
  • https://www.cnblogs.com/cherishry/p/5885107.html
  • https://blog.csdn.net/jialexiao/article/details/71124930
  • https://blog.csdn.net/longerzone/article/details/23870297
  • https://blog.csdn.net/dream_allday/article/details/75243818
  • https://blog.csdn.net/daoer_sofu/article/details/102456935

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/89791.html

標籤:Linux

上一篇:shell腳本之十四:企業案例

下一篇:Ubuntu adb 報錯:no permissions (user in plugdev group; are your udev rules wrong?);

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more