linux系統編程:自己動手寫一個pwd命令,linuxpwd
pwd命令:列印當前的工作目錄
我們都知道每個目錄下面都有兩個特殊的目錄( . 和 .. ), .: 目前的目錄, ..: 上層目錄, 每個目錄都有一個i節點與之相關聯
ghostwu@ubuntu:~$ ls -i3677860 bak 3670018 examples.desktop 1507 python3678042 core 3670033 Music 1506 shell_script 1505 c_program 3672560 note 3670169 software3672551 data 3675147 php 3678095 tags3670028 Desktop 150874 php_study 3670030 Templates3670032 Documents 3670034 Pictures 3677997 unix3670029 Downloads 3670031 Public 3670035 Videos
通過ls -i就可以顯示每個檔案和目錄的inode值,比如下面我用ls -ia顯示所有檔案的inode
1,當工作在basic目錄下面的時候, 目前的目錄basic( 也就是. )他的inode值為1573909, ..: 1507
2,當把路徑切換到python時候, .: 1507 剛好就跟basic的 .. 相等。後面依次類推
通過inode的關聯就把目錄的層級關係給找出來了,下一個問題:如何知道,已經到達根目錄?
ghostwu@ubuntu:~/python/basic$ ls -ia1573909 . 8913 person2.class.py 8405 test1.py 1507 .. 3427 person3.class.py 8897 test2.py 8910 func2.py 8916 person4.class.py 4537 test3.py 8911 func3.py 8912 person.class.py 8908 test4.py 8909 func.py 8915 superlist.class.pyghostwu@ubuntu:~/python/basic$ cd ..ghostwu@ubuntu:~/python$ ls -ia 1507 . 3670017 .. 1573911 advance 1573909 basic 151172 djangoghostwu@ubuntu:~/python$ cd ..ghostwu@ubuntu:~$ ls -ia3670017 . 3672499 .mysql_history 2 .. 3677054 .navicat64 3695 .adobe 3672560 note1050432 .atom 3675147 php...
在根目錄(/)下面的. 和 ..,他們的inode節點有個特點, 都是相等的,所以只要判斷目前的目錄的inode等於上層目錄的inode,就可以斷定,到達根目錄了
ghostwu@ubuntu:/$ ls -1ia 2 . 2 .. 915713 bin 2 boot 130818 cdrom 3 dev 523265 etc 2 home ...
1,第一個要解決的問題: 如果通過路徑/檔案名稱,得到對應的inode值,通過stat函數,獲得檔案/目錄的struct stat結構體,檔案資訊都在這裡儲存,包括inode
1 /*================================================================ 2 * Copyright (C) 2018 . All rights reserved. 3 * 4 * 檔案名稱:pwd.c 5 * 創 建 者:ghostwu(吳華) 6 * 建立日期:2018年01月10日 7 * 描 述:pwd命令編寫 8 * 9 ================================================================*/10 11 #include <stdio.h>12 #include <sys/types.h>13 #include <sys/stat.h>14 #include <unistd.h>15 #include <stdlib.h>16 17 18 //讀取當前檔案的i節點19 ino_t get_inode( char* name );20 21 int main(int argc, char *argv[])22 {23 printf( "目前的目錄.的inode=%ld\n", get_inode( "." ) );24 printf( "上層目錄..的inode=%ld\n", get_inode( ".." ) );25 return 0;26 }27 28 29 ino_t get_inode( char* name ) {30 struct stat statinfo;31 if( -1 == stat( name, &statinfo ) ) {32 printf( "檔案%s開啟失敗\n", name );33 exit( -1 );34 }35 return statinfo.st_ino;36 }View Code
2,完整的pwd源碼
1 /*================================================================ 2 * Copyright (C) 2018 . All rights reserved. 3 * 4 * 檔案名稱:pwd.c 5 * 創 建 者:ghostwu(吳華) 6 * 建立日期:2018年01月10日 7 * 描 述:pwd命令編寫 8 * 9 ================================================================*/10 11 #include <stdio.h>12 #include <sys/types.h>13 #include <sys/stat.h>14 #include <unistd.h>15 #include <stdlib.h>16 #include <dirent.h>17 #include <string.h>18 19 #ifndef BUFSIZE20 #define BUFSIZE 10021 #endif22 23 24 //讀取當前檔案的i節點25 ino_t get_inode( char* name );26 void printpathto( ino_t cur_node );27 //根據當前inode節點,找到它對應的路徑名稱28 void inode_to_name( ino_t cur_node, char* str, int bufsize );29 30 int main(int argc, char *argv[])31 {32 //printf( "目前的目錄.的inode=%ld\n", get_inode( "." ) );33 //printf( "上層目錄..的inode=%ld\n", get_inode( ".." ) );34 printpathto( get_inode( "." ) );35 putchar( '\n' );36 return 0;37 }38 39 void printpathto( ino_t cur_node ) {40 41 char dir_name[BUFSIZE];42 ino_t my_node;43 //如果當前節點不等於..,說明沒有到達根目錄44 if( cur_node != get_inode( ".." ) ) {45 //切換到上層目錄, 目前的目錄(.)的名稱在上層目錄(..)46 //所以找名稱之前,先要切換到上層目錄47 chdir( ".." );48 inode_to_name( cur_node, dir_name, BUFSIZE );49 //chdir( ".." ); //不能放在這裡,放在這裡 找不到目錄的名稱50 my_node = get_inode( "." );51 printpathto( my_node );52 printf( "/%s", dir_name );53 }54 }55 56 void inode_to_name( ino_t cur_node, char* str, int bufsize ) {57 DIR* dir_entry;58 struct dirent* pCurDir;59 if( ( dir_entry = opendir( "." ) ) == NULL ) {60 printf( "open cur directory error\n" );61 exit( -1 );62 }63 //printf( "cur inode=%ld\n", cur_node );64 while( ( pCurDir = readdir( dir_entry ) ) != NULL ) {65 if( cur_node == pCurDir->d_ino ) {66 //printf( "%s\n", pCurDir->d_name );67 strncpy( str, pCurDir->d_name, bufsize );68 str[bufsize-1] = '\0';69 closedir( dir_entry );70 return;71 }72 }73 }74 75 76 ino_t get_inode( char* name ) {77 struct stat statinfo;78 if( -1 == stat( name, &statinfo ) ) {79 printf( "檔案%s開啟失敗\n", name );80 exit( -1 );81 }82 return statinfo.st_ino;83 }View Code
運行之後的效果:
ghostwu@ubuntu:~/c_program/linux_unix/chapter4$ ./pwd/ghostwu/c_program/linux_unix/chapter4
還少了一層home,在home這層停止了
ghostwu@ubuntu:/home$ ls -ia 2 . 2 .. 3670017 ghostwu 11 lost+found
home這層確實是 . 和 ..相等? 為什麼會有這樣的情況? 因為/home這個是一個分區,在linux中,每個分區都有獨立的根目錄結構, /home就是這個分區的根節點,只不過被掛載到根分區( / )下面
總結:
1)linux檔案分區與結構
2)目錄和檔案通過inode組成級聯關係