1. 程式人生 > >2017-2018-3 20155337《信息安全系統設計基礎》 pwd指令學習

2017-2018-3 20155337《信息安全系統設計基礎》 pwd指令學習

logical “.” ont 修改時間 系統 serve find 連接 特殊

2017-2018-3 20155337《信息安全系統設計基礎》 pwd指令學習

任務要求

  • 學習pwd指令
  • 研究pwd實現需要的系統調用(man -k;grep),寫出偽代碼
  • 實現mypwd
  • 測試mypwd

任務一

學習pwd指令

該命令用來顯示目前所在的工作目錄。指令英文原義:print work directory

  • 執行權限All User
  • 指令所在路徑:/usr/bin/pwd/bin/pwd
    Linux中用 pwd 命令來查看”當前工作目錄“的完整路徑。 簡單得說,每當你在終端進行操作時,你都會有一個當前工作目錄。
    在不太確定當前位置時,就會使用pwd來判定當前目錄在文件系統內的確切位置。
參數 長參數 描述
-L -logical 當目錄為連接路徑時,顯示連接路徑
-P -physical 顯示實際物理路徑,而非使用連接(link)路徑
-help 顯示命令在線幫助
-version 顯示命令版本信息
  • 顯示當前目錄所在路徑 pwd
    技術分享圖片

  • 顯示當前目錄的物理路徑 pwd –P

[root@DB-Server init.d]# cd /etc/init.d 
 [root@DB-Server init.d]# pwd -P 
  /etc/rc.d/init.d
  • 顯示當前目錄的連接路徑:pwd -L
[root@DB-Server networking]# cd /etc/init.d 
 [root@DB-Server init.d]# pwd -L 
  /etc/init.d 
  [root@DB-Server init.d]# pwd 
  /etc/init.d

技術分享圖片

然而這裏我在運行pwd -Lpwd -P指令時顯示路徑是相通的,並沒有與期望的在網上找到的實例相同

我認為這裏是虛擬機的系統不同,在虛擬機的計算機中已經沒有r.cd這個系統文件,而是將其分為好幾個小的分組文件,而init.d也是一個獨立的文件所以pwd -L的命令鏈接路徑和物理路徑是相同路徑
技術分享圖片
技術分享圖片
技術分享圖片

(這裏查詢了pwd -Lpwd -P指令的差別)
-L
如果 PWD 環境變量包含了不包含文件名 .(點)或 ..(點點)的當前目錄的絕對路徑名,則顯示 PWD 環境變量的值。否則,-L 標誌與 -P 標誌一樣運行。
-P
顯示當前目錄的絕對路徑名。與 -P 標誌一起顯示的絕對路徑不包含在路徑名的絕對路徑中涉及到符號鏈接類型的文件的名稱。

任務二

研究pwd實現需要的系統調用(man -k;grep),寫出偽代碼

技術分享圖片
在pwd的系統點用中發現了dir的系統內部代碼,這裏查詢了dir的系統命令
技術分享圖片

  • 這裏是pwd的實現過程
    每個目錄下都至少有兩個內容‘.’和’..’,其中‘.’代表當前目錄,’..’代表上級目錄。每個目錄或文件都有對應的i-節點號,根目錄的‘.’和’..’相同,所以i-節點號相同。通過命令’ls -1ia’(數字1,不是字母l)可以查看當前目錄下的文件名和對應的i-節點號。
    技術分享圖片
    技術分享圖片
    概括來講,就是:
    1.找到本目錄的i-節點
    2.進入父目錄,找到i-節點對應的文件名
    3.循環以上過程,直到到達根目

在linux 中的文件系統中,文件=N(N>=1)個inode +M(M>=1)個數據塊。

數據塊,存放文件的內容數據,數據塊的數目根據文件內容的大小而定。

inode稱為信息節點,其作用有二:1、存儲跟文件相關的屬性信息,如修改時間、所有者、文件類型和文件長度,註意這些信息裏並沒有文件名;2、存儲指向文件內容數據塊的指針信息。

在一個文件系統中,一個inode代表一個文件,並使用一個整數值來標誌該inode,稱為inode-number,該值對於一個文件系統而言是唯一的,即通過該值可以找到其對應的inode。一般情況下,一個文件只有一個inode信息用來描述它。
技術分享圖片
目錄,在linux中,其實也是一種文件,所以它也是由“inode+數據塊”構成的。而其文件內容是一個列表,每一個列表項記錄“inode-number+filename"。

因此,我們通常所說的目錄a"包含"文件b,其實現層面上的意思是,目錄a的內容列表裏有一個關於文件b的列表項,即“b的inode-number+ b的filename”。

綜上,linux中,一個文件(包括目錄)的文件名,及文件名與inode的對應關系,都是由包含該文件的目錄所描述的。

其中,有兩個特殊的文件名“.” 和 “..”,“.”代表當前目錄自身,".."代表包含當前目錄的上一級目錄。
linux 文件系統樹:
技術分享圖片

任務三

實現mypwd

代碼如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

ino_t get_inode(char*);
void printpathto(ino_t);
void inum_to_name(ino_t,char*,int);
int main()
{
    printpathto(get_inode("."));  //print path to here
    putchar(‘\n‘);
    return 0;
}

void printpathto(ino_t this_inode)
{
    ino_t my_inode;
    char its_name[BUFSIZ];
    /*如果本目錄的i-節點與上級目錄不同,即本目錄不是根目錄*/
    if (get_inode("..")!=this_inode)                                 
    {
        chdir("..");         //進入上級目錄
        inum_to_name(this_inode,its_name,BUFSIZ);
        my_inode = get_inode(".");
        printpathto(my_inode);
        printf("/%s",its_name);
    }
}
void inum_to_name(ino_t inode_to_find,char* namebuf,int buflen)   //找到i-節點對應的文件名,並放在字符數組裏
{
    DIR* dir_ptr;
    struct dirent* direntp;
    dir_ptr = opendir(".");
    if (dir_ptr == NULL)
    {
        perror(".");
        exit(1);
    }
    /*下面這塊每太搞明白,功能是尋找制定i-節點的目錄,將目錄名復制到namebuf中。
    但是沒明 白他是怎麽尋找的*/
    /*明白了,每次循環direntp都會指向下一個文件,詳見testreaddir.c。
    但這是怎麽做到的呢?*/
    while((direntp = readdir(dir_ptr)) != NULL)
    {
        if(direntp->d_ino == inode_to_find)
        {
            strncpy(namebuf,direntp->d_name,buflen);
            namebuf[buflen-1] = ‘\0‘;
            closedir( dir_ptr);
            return;
        }
    }
    fprintf( stderr , "error looking for inum % d\n" ,inode_to_find);
    exit (1) ;
}
ino_t get_inode(char* fname)            //根據文件名,返回-i節點
{
    struct stat info;
    if ( stat( fname, &info) == -1){
        fprintf( stderr , "Cannot stat ");
        perror(fname);
        exit (1);
    }
    return info.st_ino;
}

測試結果截圖

技術分享圖片
技術分享圖片

2017-2018-3 20155337《信息安全系統設計基礎》 pwd指令學習