從零開始UNIX環(huán)境高級(jí)編程(4):文件和目錄

1. 函數(shù)stat、fstat楚里、fstata和lstat

1.1 函數(shù)描述

函數(shù)原型 描述
int stat(const char *restrict path, struct stat *restrict buf); 獲得與path有關(guān)的文件信息到buf
int fstat(int fd, struct stat *buf); 獲得與文件描述符fd有關(guān)的文件信息到buf
int fstatat(int fd, const char *path, struct stat *buf, int flag); 返回fd有關(guān)的文件信息到buf耻涛,當(dāng)flag設(shè)置為AT_SYMLINK_NOFOLLOW颈渊,功能和lstat一樣;當(dāng)path為絕對(duì)路徑時(shí)俐填,功能和stat一樣
int lstat(const char *restrict path, struct stat *restrict buf); 和stat作用類似安接,只是當(dāng)文件是一個(gè)符號(hào)鏈接時(shí),會(huì)返回符號(hào)鏈接的有關(guān)信息

1.2 stat結(jié)構(gòu)體

stat結(jié)構(gòu)體在不同的版本上實(shí)現(xiàn)會(huì)有所不同英融,在Mac OSX 10.12.2上根據(jù)宏_DARWIN_FEATURE_64_BIT_INODE是否定義盏檐,stat對(duì)應(yīng)有兩種實(shí)現(xiàn)方式。

  • _DARWIN_FEATURE_64_BIT_INODE未定義
 struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is NOT defined */
     dev_t    st_dev;    /* device inode resides on */
     ino_t    st_ino;    /* inode's number */
     mode_t   st_mode;   /* inode protection mode */
     nlink_t  st_nlink;  /* number of hard links to the file */
     uid_t    st_uid;    /* user-id of owner */
     gid_t    st_gid;    /* group-id of owner */
     dev_t    st_rdev;   /* device type, for special file inode */
     struct timespec st_atimespec;  /* time of last access */
     struct timespec st_mtimespec;  /* time of last data modification */
     struct timespec st_ctimespec;  /* time of last file status change */
     off_t    st_size;   /* file size, in bytes */
     quad_t   st_blocks; /* blocks allocated for file */
     u_long   st_blksize;/* optimal file sys I/O ops blocksize */
     u_long   st_flags;  /* user defined flags for file */
     u_long   st_gen;    /* file generation number */
 };
  • _DARWIN_FEATURE_64_BIT_INODE已定義
 struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is defined */
     dev_t           st_dev;           /* ID of device containing file */
     mode_t          st_mode;          /* Mode of file (see below) */
     nlink_t         st_nlink;         /* Number of hard links */
     ino_t           st_ino;           /* File serial number */
     uid_t           st_uid;           /* User ID of the file */
     gid_t           st_gid;           /* Group ID of the file */
     dev_t           st_rdev;          /* Device ID */
     struct timespec st_atimespec;     /* time of last access */
     struct timespec st_mtimespec;     /* time of last data modification */
     struct timespec st_ctimespec;     /* time of last status change */
     struct timespec st_birthtimespec; /* time of file creation(birth) */
     off_t           st_size;          /* file size, in bytes */
     blkcnt_t        st_blocks;        /* blocks allocated for file */
     blksize_t       st_blksize;       /* optimal blocksize for I/O */
     uint32_t        st_flags;         /* user defined flags for file */
     uint32_t        st_gen;           /* file generation number */
     int32_t         st_lspare;        /* RESERVED: DO NOT USE! */
     int64_t         st_qspare[2];     /* RESERVED: DO NOT USE! */
 };
  • 通過一段代碼來驗(yàn)證_DARWIN_FEATURE_64_BIT_INODE是否定義
#include "../inc/apue.h"

int main(int argc, char const *argv[])
{
#if defined(_DARWIN_FEATURE_64_BIT_INODE)
    printf("_DARWIN_FEATURE_64_BIT_INODE is defined\n");
#else
    printf("_DARWIN_FEATURE_64_BIT_INODE is not defined \n");
#endif
    return 0;
}

運(yùn)行結(jié)果

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./stat_test 
_DARWIN_FEATURE_64_BIT_INODE is defined

2. 文件類型

2.1 分類

文件分類如下:


文件類型

文件類型可以通過結(jié)構(gòu)體stat中的成員st_mode獲取驶悟,不同類型對(duì)應(yīng)的值都定義在頭文件 /usr/include/sys/stat.h中:

 #define S_IFMT 0170000           /* type of file */
 #define        S_IFIFO  0010000  /* named pipe (fifo) */
 #define        S_IFCHR  0020000  /* character special */
 #define        S_IFDIR  0040000  /* directory */
 #define        S_IFBLK  0060000  /* block special */
 #define        S_IFREG  0100000  /* regular */
 #define        S_IFLNK  0120000  /* symbolic link */
 #define        S_IFSOCK 0140000  /* socket */
 #define        S_IFWHT  0160000  /* whiteout */
 #define S_ISUID 0004000  /* set user id on execution */
 #define S_ISGID 0002000  /* set group id on execution */
 #define S_ISVTX 0001000  /* save swapped text even after use */
 #define S_IRUSR 0000400  /* read permission, owner */
 #define S_IWUSR 0000200  /* write permission, owner */
 #define S_IXUSR 0000100  /* execute/search permission, owner */

2.2 獲取文件類型 - 示例

  • code
#include "../inc/apue.h"

int main(int argc, char const *argv[])
{
    struct stat buf;
    char *ptr;

    if (argc != 2)
    {
        printf("please input a filename\n");
        return 0;
    }

    if (lstat(argv[1], &buf) < 0 )
        err_ret("lstat error");

    if (S_ISREG(buf.st_mode))
        ptr = "regular";
    else if (S_ISDIR(buf.st_mode))
        ptr = "directory";
    else if (S_ISLNK(buf.st_mode))
        ptr = "symbolic link";
    else
        ptr = "unknown mode";

    printf("%s\n", ptr);

    return 0;
}

早期的unix版本不提供S_ISxxx宏胡野,需要先將st_mode與屏蔽字S_IFMT進(jìn)行與運(yùn)算,然后在和S_IFxxx常量進(jìn)行比較才能得出對(duì)應(yīng)的文件類型痕鳍。S_ISxxx宏定義如下:

#define S_ISBLK(m)  (((m) & S_IFMT) == S_IFBLK) /* block special */
#define S_ISCHR(m)  (((m) & S_IFMT) == S_IFCHR) /* char special */
#define S_ISDIR(m)  (((m) & S_IFMT) == S_IFDIR) /* directory */
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) /* fifo or socket */
#define S_ISREG(m)  (((m) & S_IFMT) == S_IFREG) /* regular file */
#define S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK) /* symbolic link */
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)    /* socket */
  • 運(yùn)行結(jié)果
zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ cc get_file_type.c -o get_file_type
zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./get_file_type /dev/zero 
unknown mode
zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./get_file_type get_file_type.c 
regular
zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./get_file_type .
directory
zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./get_file_type /dev/stdin 
symbolic link

使用ls命令查看文件屬性硫豆,和程序運(yùn)行結(jié)果一致

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ls -dl get_file_type.c /dev/zero . /dev/stdin 
drwxr-xr-x  6 zhanghuamao  staff       204  2 11 09:58 .
lr-xr-xr-x  1 root         wheel         0  2 11 09:39 /dev/stdin -> fd/0
crw-rw-rw-  1 root         wheel    3,   3  2 11 09:39 /dev/zero
-rw-r--r--@ 1 zhanghuamao  staff       453  2 11 10:01 get_file_type.c

3. 訪問權(quán)限

3.1 文件權(quán)限

  • 可讀權(quán)限

使用chmod命令去掉文件的r權(quán)限,執(zhí)行cp復(fù)制文件時(shí)笼呆,會(huì)報(bào)錯(cuò)"cp: file.txt: Permission denied
"
熊响,說明復(fù)制文件需要r權(quán)限

zhanghuamaodeMacBook-Pro:test zhanghuamao$ sudo chmod a-r file.txt 

zhanghuamaodeMacBook-Pro:test zhanghuamao$ cp file.txt file.txt.bk
cp: file.txt: Permission denied

給文件用戶添加可讀權(quán)限,復(fù)制成功

zhanghuamaodeMacBook-Pro:test zhanghuamao$ sudo chmod u+r file.txt 

zhanghuamaodeMacBook-Pro:test zhanghuamao$ ls -l file.txt
-rw-------  1 zhanghuamao  staff  0  2 11 14:15 file.txt

zhanghuamaodeMacBook-Pro:test zhanghuamao$ cp file.txt file.txt.bk

zhanghuamaodeMacBook-Pro:test zhanghuamao$ ls -l
total 0
-rw-------  1 zhanghuamao  staff    0  2 11 14:15 file.txt
-rw-------  1 zhanghuamao  staff    0  2 11 14:18 file.txt.bk

3.2 目錄權(quán)限

  • 可讀權(quán)限

目錄要具有可讀權(quán)限诗赌,才能使用ls命令

zhanghuamaodeMacBook-Pro:code zhanghuamao$ sudo chmod a-r test/ ; ls -dl test/;ls -al test/
d-wx--x--x  4 zhanghuamao  staff  136  2 11 14:22 test/
ls: : Permission denied
  • 可執(zhí)行權(quán)限

目錄要具有可執(zhí)行權(quán)限耘眨,才能進(jìn)入

zhanghuamaodeMacBook-Pro:code zhanghuamao$ sudo chmod a-x test/

zhanghuamaodeMacBook-Pro:code zhanghuamao$ ls -dl test/ ; cd test/
drw-r--r--  2 zhanghuamao  staff  68  2 11 11:21 test/
-bash: cd: test/: Permission denied

3.3 用戶ID和組ID

  • 實(shí)際用戶ID、實(shí)際組ID和有效用戶ID境肾、有效組ID

通常剔难,有效用戶ID = 實(shí)際用戶ID,每個(gè)文件的所有者有stat中的st_uid指定奥喻;
當(dāng)執(zhí)行一個(gè)程序文件時(shí)偶宫,進(jìn)程的有效用戶ID通常就是實(shí)際用戶ID。但是环鲤,當(dāng)設(shè)置了特殊標(biāo)志時(shí)纯趋,當(dāng)執(zhí)行此文件時(shí),進(jìn)程的有效用戶ID = 文件所有者的用戶ID

  • code
#include "apue.h"
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    struct stat buf;
    char *ptr;

    if (argc != 2)
    {
        printf("please input a filename\n");
        return 0;
    }

    if (access(argv[1], R_OK) < 0 )
        err_ret("access error for %s", argv[1]);
    else
        printf("read access OK\n");

    if (open(argv[1], O_RDONLY) < 0)
        err_ret("open error for %s", argv[1]);
    else
        printf("open for reading OK\n");

    return 0;
}
  • output
ckt@ubuntu:~/work/unix/code/chapter4$ cc access_test.c -o access_test
ckt@ubuntu:~/work/unix/code/chapter4$ ls -l access_test
-rwxrwxr-x 1 ckt ckt 13419 Feb 12 18:46 access_test

ckt@ubuntu:~/work/unix/code/chapter4$ ls -l /etc/shadow
-rw-r----- 1 root shadow 1129 Sep 19 23:17 /etc/shadow

ckt@ubuntu:~/work/unix/code/chapter4$ ./access_test /etc/shadow
access error for /etc/shadow: Permission denied
open error for /etc/shadow: Permission denied

ckt@ubuntu:~/work/unix/code/chapter4$ sudo chown root access_test
ckt@ubuntu:~/work/unix/code/chapter4$ sudo chmod u+s access_test

ckt@ubuntu:~/work/unix/code/chapter4$ ls -l access_test
-rwsrwxr-x 1 root ckt 13419 Feb 12 18:46 access_test
ckt@ubuntu:~/work/unix/code/chapter4$ ./access_test /etc/shadow
access error for /etc/shadow: Permission denied
open for reading OK

3.4 默認(rèn)權(quán)限:umask

  • 查看默認(rèn)權(quán)限

zhanghuamaodeMacBook-Pro:test zhanghuamao$ umask; umask -S
0022
u=rwx,g=rx,o=rx

umask的分?jǐn)?shù)0022指的是“該默認(rèn)值需要減掉的權(quán)限”,umask一共4組數(shù)字吵冒,第一組是特殊權(quán)限用的纯命,后面3組為user、group痹栖、other的默認(rèn)分值

  • 文件和目錄的默認(rèn)權(quán)限

用戶建文件時(shí)亿汞,默認(rèn)沒有可執(zhí)行權(quán)限,即只有r揪阿、w這兩個(gè)選項(xiàng)疗我,默認(rèn)權(quán)限為-rw-rw-rw
新建文件時(shí)默認(rèn)權(quán)限計(jì)算方式:(-rwxrw-rw-) - (------w--w) = -rw-r--r--

zhanghuamaodeMacBook-Pro:test zhanghuamao$ touch test ; ls -l
total 0
-rw-r--r--  1 zhanghuamao  staff  0  2 11 15:03 test

用戶創(chuàng)建目錄時(shí),由于x與是否進(jìn)入目錄有關(guān)南捂,因此默認(rèn)3個(gè)權(quán)限都開放:-rwxrwxrwx
新建目錄時(shí)默認(rèn)權(quán)限計(jì)算方式:(-rwxrwxrwx) - (------w--w) = -rwxr-xr-x

zhanghuamaodeMacBook-Pro:test zhanghuamao$ mkdir dir; ls -l
total 0
drwxr-xr-x  2 zhanghuamao  staff  68  2 11 15:06 dir
-rw-r--r--  1 zhanghuamao  staff   0  2 11 15:03 test

3.5 umask函數(shù)

  • 函數(shù)原型
    mode_t umask(mode_t mask); 吴裤, 其中的參數(shù)mask的值定義在/usr/include/sys/stat.h中:
#define S_IRUSR __S_IREAD   /* Read by owner.  */
#define S_IWUSR __S_IWRITE  /* Write by owner.  */
#define S_IXUSR __S_IEXEC   /* Execute by owner.  */
/* Read, write, and execute by owner.  */
#define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC)

#define S_IRGRP (S_IRUSR >> 3)  /* Read by group.  */
#define S_IWGRP (S_IWUSR >> 3)  /* Write by group.  */
#define S_IXGRP (S_IXUSR >> 3)  /* Execute by group.  */
/* Read, write, and execute by group.  */
#define S_IRWXG (S_IRWXU >> 3)

#define S_IROTH (S_IRGRP >> 3)  /* Read by others.  */
#define S_IWOTH (S_IWGRP >> 3)  /* Write by others.  */
#define S_IXOTH (S_IXGRP >> 3)  /* Execute by others.  */
/* Read, write, and execute by others.  */
#define S_IRWXO (S_IRWXG >> 3)
  • code
#include "apue.h"
#include <fcntl.h>

#define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)

int main(int argc, char const *argv[])
{
    umask(0);
    if (creat("test", RWRWRW) < 0 )
        err_sys("create error for test");
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if (creat("test2", RWRWRW) < 0 )
        err_sys("create error for test2");
    return 0;
}
  • output
ckt@ubuntu:~/work/unix/code/chapter4$ cc umask_test.c -o umask_test

ckt@ubuntu:~/work/unix/code/chapter4$ umask 
0002

ckt@ubuntu:~/work/unix/code/chapter4$ ./umask_test
ckt@ubuntu:~/work/unix/code/chapter4$ ls -l test*
-rw-rw-rw- 1 ckt ckt 0 Feb 12 21:53 test
-rw------- 1 ckt ckt 0 Feb 12 21:53 test2

ckt@ubuntu:~/work/unix/code/chapter4$ umask
0002

3.6 chmod函數(shù)

  • code
#include "apue.h"

int main(int argc, char const *argv[])
{
    struct stat statbuf;
    if (stat("test", &statbuf) < 0 )
        err_sys("stat error for test");
    
    if (chmod("test", (statbuf.st_mode & ~S_IWGRP) |  S_IXGRP) < 0 )
        err_sys("chmod error for test");

    if (chmod("test2", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0 )
        err_sys("chmod error for test2");

    return 0;
}
  • output
ckt@ubuntu:~/work/unix/code/chapter4$ ls -l test*
-rw-rw-rw- 1 ckt ckt 0 Feb 13 00:17 test
-rw------- 1 ckt ckt 0 Feb 13 00:17 test2

ckt@ubuntu:~/work/unix/code/chapter4$ cc chmod_test.c -o chmod_test
ckt@ubuntu:~/work/unix/code/chapter4$ ./chmod_test
ckt@ubuntu:~/work/unix/code/chapter4$ ls -l test*
-rw-r-xrw- 1 ckt ckt 0 Feb 13 00:17 test
-rw-rw---- 1 ckt ckt 0 Feb 13 00:17 test2

3.7 chown函數(shù)

  • code
#include "apue.h"

int main(int argc, char const *argv[])
{
    if (chown("test", getuid(), getgid()) < 0 )
        err_sys("chmod error for test");

    return 0;
}
  • output
ckt@ubuntu:~/work/unix/code/chapter4$ cc chown_test.c -o chown_test
ckt@ubuntu:~/work/unix/code/chapter4$ ls -l test
-rw------- 1 ckt ckt 0 Feb 13 00:17 test

ckt@ubuntu:~/work/unix/code/chapter4$ sudo ./chown_test
ckt@ubuntu:~/work/unix/code/chapter4$ ls -l test
-rw------- 1 root root 0 Feb 13 00:17 test

4. 文件系統(tǒng)

4.1 硬鏈接和軟鏈接對(duì)比

在link目錄下,使用link命令給test目錄下的file文件創(chuàng)建一個(gè)硬鏈接hard_link溺健,file和hard_link的inode相同麦牺,都為1000760

zhanghuamaodeMacBook-Pro:link zhanghuamao$ link ../test/file hard_link
zhanghuamaodeMacBook-Pro:link zhanghuamao$ ls -li hard_link ../test/file 
1000760 -rw-r--r--  2 zhanghuamao  staff  0  2 12 11:36 ../test/file
1000760 -rw-r--r--  2 zhanghuamao  staff  0  2 12 11:36 hard_link

使用ls -li查看link和test目錄的inode號(hào),分別為1000766鞭缭、100068

zhanghuamaodeMacBook-Pro:code zhanghuamao$ ls -li
1000766 drwxr-xr-x   2 zhanghuamao  staff   68  2 12 11:37 link
1000688 drwxr-xr-x   3 zhanghuamao  staff  102  2 12 11:36 test

再使用ln -s命令給file文件創(chuàng)建一個(gè)軟鏈接soft_link剖膳,查看soft_link的inode號(hào)為1000805,和file的inode號(hào)不一樣缚去。

zhanghuamaodeMacBook-Pro:link zhanghuamao$ ln -s ../test/file soft_link
zhanghuamaodeMacBook-Pro:link zhanghuamao$ ls -il ../test/file soft_link
1000760 -rw-r--r--  2 zhanghuamao  staff   0  2 12 11:36 ../test/file
1000805 lrwxr-xr-x  1 zhanghuamao  staff  12  2 12 11:40 soft_link -> ../test/

往hard_link文件中添加內(nèi)容"add by hard link"潮秘,使用cat命令查看soft_link和file文件,內(nèi)容都同步更新了易结。

zhanghuamaodeMacBook-Pro:link zhanghuamao$ cat soft_link ../test/file 
add by hard link
add by hard link

刪除file文件枕荞,再次使用cat命令查看soft_link和hard_link文件,soft_link提示"No such file or directory"搞动,而hard_link文件仍然存在躏精。

zhanghuamaodeMacBook-Pro:link zhanghuamao$ rm ../test/file 
zhanghuamaodeMacBook-Pro:link zhanghuamao$ cat soft_link hard_link 
cat: soft_link: No such file or directory
add by hard link

創(chuàng)建硬鏈接后,inode和bloack data示意圖


硬鏈接

當(dāng)刪除file文件時(shí)鹦肿,hard_link仍然可以通過編號(hào)為1000760的inode訪問文件內(nèi)容

硬鏈接 - 刪除file文件后

創(chuàng)建軟鏈接后矗烛,inode和bloack data示意圖

軟鏈接

當(dāng)刪除file文件后,soft_link無法再通過test目錄的inode號(hào)訪問file文件

軟鏈接 - 刪除file文件

4.2 獲取文件的硬鏈接

  • code
#include "../inc/apue.h"

int main(int argc, char const *argv[])
{
    struct stat buf;
    char *ptr;

    if (argc != 2)
    {
        printf("please input a filename\n");
        return 0;
    }

    if (lstat(argv[1], &buf) < 0 )
        err_ret("lstat error");

    printf("The hard link count of %s : %d\n", argv[1], buf.st_nlink);

    return 0;
}
  • output

先ls -il查看hard_link文件的鏈接數(shù)為3

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ls -il ../link/hard_link*
1005313 -rw-r--r--  3 zhanghuamao  staff  0  2 12 16:20 ../link/hard_link
1005313 -rw-r--r--  3 zhanghuamao  staff  0  2 12 16:20 ../link/hard_link1
1005313 -rw-r--r--  3 zhanghuamao  staff  0  2 12 16:20 ../link/hard_link2

運(yùn)行l(wèi)ink_text程序查看hard_link文件的鏈接數(shù)箩溃,和ls -il得到的結(jié)果一致瞭吃,都為3

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ cc link_text.c -o link_text
zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./link_text ../link/hard_link
The hard link count of ../link/hard_link : 3

4.3 link函數(shù)

  • code
#include "../inc/apue.h"

int main(int argc, char const *argv[])
{
    struct stat buf;
    char *ptr;

    if (argc != 3)
    {
        printf("please input a filename\n");
        return 0;
    }

    link(argv[1], argv[2]);

    return 0;
}
  • output

運(yùn)行程序my_link創(chuàng)建my_link.c的硬鏈接文件my_link_hard_link.txt

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ cc my_link.c -o my_link

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ls
get_file_type   link_text   my_link     stat_test
get_file_type.c link_text.c my_link.c   stat_test.c

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./my_link my_link.c my_link_hard_link.txt

運(yùn)行完成后使用ls -il查看,my_link.c和my_link_hard_link.txt的inode號(hào)一樣都為1006798

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ls -il my*
1006809 -rwxr-xr-x  1 zhanghuamao  staff  13596  2 12 16:56 my_link
1006798 -rw-r--r--@ 2 zhanghuamao  staff    275  2 12 16:55 my_link.c
1006798 -rw-r--r--@ 2 zhanghuamao  staff    275  2 12 16:55 my_link_hard_link.txt

4.4 unlink函數(shù)

  • code
#include "../inc/apue.h"

int main(int argc, char const *argv[])
{
    struct stat buf;
    char *ptr;

    if (argc != 2)
    {
        printf("please input a filename\n");
        return 0;
    }

    unlink(argv[1]);

    return 0;
}
  • output

運(yùn)行程序my_unlink取消掉之前創(chuàng)建的my_link_hard_link.txt

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ cc my_unlink.c -o my_unlink

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./my_unlink my_link_hard_link.txt 

已經(jīng)沒有my_link_hard_link.txt 這支文件了

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ls -il my*
1006809 -rwxr-xr-x  1 zhanghuamao  staff  13596  2 12 16:56 my_link
1006798 -rw-r--r--@ 1 zhanghuamao  staff    210  2 12 17:05 my_link.c
1006904 -rwxr-xr-x  1 zhanghuamao  staff  13596  2 12 17:06 my_unlink
1006865 -rw-r--r--@ 1 zhanghuamao  staff    203  2 12 17:06 my_unlink.c

4.5 rename函數(shù)

  • code
#include "../inc/apue.h"

int main(int argc, char const *argv[])
{
    struct stat buf;
    char *ptr;

    if (argc != 3)
    {
        printf("please input a filename\n");
        return 0;
    }

    rename(argv[1], argv[2]);

    return 0;
}
  • output

運(yùn)行程序my_mv創(chuàng)建硬鏈接前涣旨,先查看當(dāng)前已使用inode個(gè)數(shù)為793518

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ cc my_mv.c -o my_mv

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ df .
Filesystem 512-blocks     Used Available Capacity iused      ifree %iused  Mounted on
/dev/disk1  487686144 65661544 421512600    14%  793518 4294173761    0%   /

運(yùn)行程序my_mv創(chuàng)建my_mv.c的硬鏈接my_mv_rename.txt歪架,查看它們的inode號(hào)都為1007929,并且已使用inode個(gè)數(shù)和創(chuàng)建硬鏈接前一樣霹陡。

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./my_mv my_mv.c my_mv_rename.txt

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ df .
Filesystem 512-blocks     Used Available Capacity iused      ifree %iused  Mounted on
/dev/disk1  487686144 65663336 421510808    14%  793518 4294173761    0%   /

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ls -il my_m*
1007936 -rwxr-xr-x  1 zhanghuamao  staff  13596  2 12 17:37 my_mv
    1007929 -rwxr-xr-x  1 zhanghuamao  staff    212  2 12 17:37 my_mv.c
1007929 -rwxr-xr-x  1 zhanghuamao  staff    212  2 12 17:37 my_mv_rename.txt

4.6 symlink函數(shù)

  • code
#include "../inc/apue.h"

int main(int argc, char const *argv[])
{
    struct stat buf;
    char *ptr;

    if (argc != 3)
    {
        printf("please input a filename\n");
        return 0;
    }

    symlink(argv[1], argv[2]);

    return 0;
}
  • output

在運(yùn)行程序my_ln創(chuàng)建軟鏈接前和蚪,先使用df命令查看當(dāng)前已用inode個(gè)數(shù)為793532

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ cc my_ln.c -o my_ln 

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ df .
Filesystem 512-blocks     Used Available Capacity iused      ifree %iused  Mounted on
/dev/disk1  487686144 65664040 421510104    14%  793532 4294173747    0%   /

運(yùn)行程序my_ln創(chuàng)建my_ln.c的軟鏈接my_ln_soft_link.txt止状,查看它們的inode號(hào)分別是1008145和1008163

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./my_ln my_ln.c my_ln_soft_link.txt

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ls -il my_ln*
1008156 -rwxr-xr-x  1 zhanghuamao  staff  13604  2 12 17:50 my_ln
1008145 -rw-r--r--@ 1 zhanghuamao  staff    213  2 12 17:49 my_ln.c
1008163 lrwxr-xr-x  1 zhanghuamao  staff      7  2 12 17:51 my_ln_soft_link.txt -> my_ln.c

再次使用df命令查看當(dāng)前已用inode個(gè)數(shù)為793533,比運(yùn)行程序my_ln前攒霹,少了一個(gè)inode號(hào)

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ df .
Filesystem 512-blocks     Used Available Capacity iused      ifree %iused  Mounted on
/dev/disk1  487686144 65663920 421510224    14%  793533 4294173746    0%   /

將my_ln.c刪除怯疤,再去cat my_ln_soft_link.txt,提示錯(cuò)誤"cat: my_ln_soft_link.txt: No such file or directory"

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ rm my_ln.c ; cat my_ln_soft_link.txt
cat: my_ln_soft_link.txt: No such file or directory

4.7 時(shí)間參數(shù)

Unix中一共有3個(gè)時(shí)間參數(shù)催束,這3個(gè)值被記錄在stat成員變量中:

 struct timespec st_atimespec;  /* time of last access */
 struct timespec st_mtimespec;  /* time of last data modification */
 struct timespec st_ctimespec;  /* time of last file status change */
  • modification time(mtime)
    當(dāng)修改文件內(nèi)容時(shí)集峦,mtime會(huì)更新,使用ls -l命令查看的時(shí)間就是mtime
ckt@ubuntu:~/work/unix/code/chapter4$ ls -l ../chapter2/limits_test.c 
-rwxr--r-- 1 ckt ckt 179 Jan 15 22:10 ../chapter2/limits_test.c
  • acess time(atime)
    當(dāng)文件內(nèi)容被取用時(shí)泣崩,就會(huì)更新atime少梁。例如洛口,使用cat去讀取文件時(shí)矫付。
    使用命令ls -l --time=atime可以查看atime
ckt@ubuntu:~/work/unix/code/chapter4$ cat ../chapter2/limits_test.c 
cat內(nèi)容省略
ckt@ubuntu:~/work/unix/code/chapter4$ls -l ../chapter2/limits_test.c
-rwxr--r-- 1 ckt ckt 179 Jan 15 22:10 ../chapter2/limits_test.c

ckt@ubuntu:~/work/unix/code/chapter4$ ls -l --time=atime ../chapter2/limits_test.c 
-rwxr--r-- 1 ckt ckt 179 Feb 13 01:00 ../chapter2/limits_test.c

ckt@ubuntu:~/work/unix/code/chapter4$ date
Mon Feb 13 01:01:12 PST 2017
  • status time(ctime)
    當(dāng)文件的狀態(tài)改變時(shí),就會(huì)更新這個(gè)時(shí)間第焰,例如:權(quán)限與屬性被更改了
    使用命令ls -l --time=ctime可以查看ctime
ckt@ubuntu:~/work/unix/code/chapter4$ chmod 644 ../chapter2/limits_test.c 
ckt@ubuntu:~/work/unix/code/chapter4$ ls -l --time=ctime ../chapter2/limits_test.c 
-rw-r--r-- 1 ckt ckt 179 Feb 13 01:03 ../chapter2/limits_test.c

4.8 打印設(shè)備ID

  • code
#include "apue.h"
#include <sys/sysmacros.h>

int main(int argc, char const *argv[])
{
    struct stat buf;

    if (argc != 2)
    {
        printf("please input a filename\n");
        return 0;
    }

    if (lstat(argv[1], &buf) < 0 )
        err_ret("lstat error");

    printf("dev = %d / %d ", major(buf.st_dev), minor(buf.st_dev));
    
    if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode))
    {
        printf(", rdev = %d / %d ", major(buf.st_rdev), minor(buf.st_rdev));
    }

    printf("\n");
    return 0;
}
  • output
ckt@ubuntu:~/work/unix/code/chapter4$ cc dev_test.c -o dev_test
ckt@ubuntu:~/work/unix/code/chapter4$ ./dev_test /dev/tty1
dev = 0 / 5 , rdev = 4 / 1 
ckt@ubuntu:~/work/unix/code/chapter4$ ./dev_test dev_test
dev = 8 / 17 

5. 目錄操作

5.1 mkdir函數(shù)

  • code
#include "apue.h"

#define RWXRXRX (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)

int main(int argc, char const *argv[])
{
    if (argc != 2)
    {
        printf("please input a filename\n");
        return 0;
    }

    if (mkdir(argv[1], RWXRXRX) < 0 )
        err_ret("mkdir error");
    return 0;
}
  • output
ckt@ubuntu:~/work/unix/code/chapter4$ cc mkdir_test.c -o mkdir_test
ckt@ubuntu:~/work/unix/code/chapter4$ ./mkdir_test 222
ckt@ubuntu:~/work/unix/code/chapter4$ ls -dl 222
drwxr-xr-x 2 ckt ckt 4096 Feb 15 01:14 222

5.2 rmdir函數(shù)

  • code
#include "apue.h"

int main(int argc, char const *argv[])
{
    if (argc != 2)
    {
        printf("please input a filename\n");
        return 0;
    }

    if (rmdir(argv[1]) < 0 )
        err_ret("rmdir error");
    return 0;
}
  • output
ckt@ubuntu:~/work/unix/code/chapter4$ cc rmdir_test.c -o rmdir_test
ckt@ubuntu:~/work/unix/code/chapter4$ ./rmdir_test 222/
ckt@ubuntu:~/work/unix/code/chapter4$ ls -dl 222
ls: cannot access 222: No such file or directory

5.3 chdir函數(shù)

  • code
#include "apue.h"

int main(int argc, char const *argv[])
{
    if (chdir("/home") < 0 )
        err_ret("chdir error");

    printf("chdir to /home succeeded\n");

    printf("current path = %s\n", get_current_dir_name());
    return 0;
}
  • output
    運(yùn)行程序chdir_test后买优,shell顯示的當(dāng)前目錄并沒有改變,這是因?yàn)槊總€(gè)程序運(yùn)行在獨(dú)立的進(jìn)程中挺举,shell的當(dāng)前工作目錄并不會(huì)隨著程序調(diào)用chdir而改變杀赢。但是,chdir_test程序通過調(diào)用get_current_dir_name函數(shù)湘纵,可以將當(dāng)前目錄名稱打印出來脂崔,由此可以證明chdir已經(jīng)生效
ckt@ubuntu:~/work/unix/code/chapter4$ cc chdir_test.c -o chdir_test

ckt@ubuntu:~/work/unix/code/chapter4$ ./chdir_test
chdir to /home succeeded
current path = /home

5.4 讀目錄

  • code
#include "../inc/apue.h"
#include <dirent.h>

int main(int argc, char const *argv[])
{
    DIR *dirp;
    struct dirent *dp;

    dirp = opendir("../");

    if (dirp == NULL)
        return 0;

    while ((dp = readdir(dirp)) != NULL)
    {
        printf("%s\n", dp->d_name);
    }

    return 0;
}
  • output
zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ cc readdir_test.c -o readdir_test
zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ./readdir_test 
.
..
chapter3
chapter4
file1
file2
inc
link
test

zhanghuamaodeMacBook-Pro:chapter4 zhanghuamao$ ls -l ../
total 0
drwxr-xr-x  17 zhanghuamao  staff  578  1 22 21:55 chapter3
drwxr-xr-x  21 zhanghuamao  staff  714  2 15 23:18 chapter4
-rw-r--r--   1 zhanghuamao  staff    0  2 15 23:01 file1
-rw-r--r--   1 zhanghuamao  staff    0  2 15 23:01 file2
drwxr-xr-x   4 zhanghuamao  staff  136  1 21 10:06 inc
drwxr-xr-x   8 zhanghuamao  staff  272  2 12 16:25 link
drwxr-xr-x   2 zhanghuamao  staff   68  2 12 11:43 test

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市梧喷,隨后出現(xiàn)的幾起案子砌左,更是在濱河造成了極大的恐慌,老刑警劉巖铺敌,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汇歹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡偿凭,警方通過查閱死者的電腦和手機(jī)产弹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弯囊,“玉大人痰哨,你說我怎么就攤上這事∝抑觯” “怎么了斤斧?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長奄毡。 經(jīng)常有香客問我折欠,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任锐秦,我火速辦了婚禮咪奖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酱床。我一直安慰自己羊赵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布扇谣。 她就那樣靜靜地躺著昧捷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪罐寨。 梳的紋絲不亂的頭發(fā)上靡挥,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音鸯绿,去河邊找鬼跋破。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瓶蝴,可吹牛的內(nèi)容都是我干的毒返。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼舷手,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拧簸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起男窟,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤盆赤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蝎宇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弟劲,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年姥芥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兔乞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凉唐,死狀恐怖庸追,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情台囱,我是刑警寧澤淡溯,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站簿训,受9級(jí)特大地震影響咱娶,放射性物質(zhì)發(fā)生泄漏米间。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一膘侮、第九天 我趴在偏房一處隱蔽的房頂上張望屈糊。 院中可真熱鬧,春花似錦琼了、人聲如沸逻锐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昧诱。三九已至,卻和暖如春所袁,著一層夾襖步出監(jiān)牢的瞬間盏档,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國打工纲熏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妆丘,地道東北人锄俄。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓局劲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奶赠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鱼填,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • inode是什么 理解inode,要從文件儲(chǔ)存說起毅戈。文件儲(chǔ)存在硬盤上苹丸,硬盤的最小存儲(chǔ)單位叫做"扇區(qū)"(Sector...
    狗尾巴草敗了閱讀 694評(píng)論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)苇经,斷路器赘理,智...
    卡卡羅2017閱讀 134,708評(píng)論 18 139
  • 轉(zhuǎn)自:http://www.ruanyifeng.com/blog/2011/12/inode.htmlhttp:...
    JackyTsuuuy閱讀 432評(píng)論 0 3
  • Ubuntu的發(fā)音 Ubuntu蜘澜,源于非洲祖魯人和科薩人的語言施流,發(fā)作 oo-boon-too 的音。了解發(fā)音是有意...
    螢火蟲de夢(mèng)閱讀 99,366評(píng)論 9 467
  • 內(nèi)容詳情 導(dǎo)航 2017事業(yè)單位醫(yī)療考試面試:處理方式題的答題思路 17-06-02 選課 體驗(yàn) 資訊 題庫 技巧...
    我的世界1234閱讀 189評(píng)論 1 1