UNIX再学习 -- 文件和目录
文件I/O部分断断续续写了三天,最后总结发现还有好多内容是略过没讲的,我的内心是崩溃的。UNIX环境高级编程这本书,虽然我只看了四章我就发现了书里面的内容讲的太跳,如果是刚接触UNIX或者没有一点C语言基础的会很难上手。这就造成了,前面讲的会漏掉很多内容。
一、函数 stat、fstat、fstatat 和 lstat
详细内容可 man fstat 查看
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
1、参数解析
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 */};
其中时间函数部分,参看:C语言再学习 -- 时间函数
2、返回值
3、函数功能
4、示例说明
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>int main (void)
{struct stat st = {};int res = stat ("a.txt", &st);if (-1 == res)perror ("Fail to stat"), exit (1);printf ("st_mode = %o, st_size = %ld, st_mtime = %ld\n", st.st_mode, st.st_size, st.st_mtime);printf ("文件的权限是:%o\n", st.st_mode&0777);printf ("文件的大小是:%ld\n", st.st_size);if (S_ISREG (st.st_mode))printf ("是普通文件\n");if (S_ISDIR (st.st_mode))printf ("是目录文件\n");printf ("最后一次修改时间是:%s\n", ctime (&st.st_mtime));struct tm* pt = localtime (&st.st_mtime);printf("最后一次修改时间是:%d-%d-%d %02d:%02d:%02d\n",pt->tm_year+1900,pt->tm_mon+1,pt->tm_mday,pt->tm_hour,pt->tm_min,pt->tm_sec);return 0;
}
输出结果:
st_mode = 100644, st_size = 0, st_mtime = 1490857501
文件的权限是:644
文件的大小是:0
是普通文件
最后一次修改时间是:Thu Mar 30 15:05:01 2017最后一次修改时间是:2017-3-30 15:05:01
5、总结
这部分只讲函数 stat,其实在 Linux 下 stat 命令 也可以实现这些功能了。 参看:stat 命令
# stat c_test/文件:"c_test/"大小:4096 块:8 IO 块:4096 目录
设备:801h/2049d Inode:2102110 硬链接:2
权限:(0775/drwxrwxr-x) Uid:( 1000/ tarena) Gid:( 1000/ tarena)
最近访问:2017-03-30 15:05:03.502154419 +0800
最近更改:2017-03-30 15:05:01.858151879 +0800
最近改动:2017-03-30 15:05:01.858151879 +0800
创建时间:-# stat a.txt 文件:"a.txt"大小:0 块:0 IO 块:4096 普通空文件
设备:801h/2049d Inode:2121684 硬链接:1
权限:(0644/-rw-r--r--) Uid:( 0/ root) Gid:( 0/ root)
最近访问:2017-03-30 15:05:01.858151879 +0800
最近更改:2017-03-30 15:05:01.858151879 +0800
最近改动:2017-03-30 15:05:01.858151879 +0800
创建时间:-
二、文件类型
1、普通文件
2、目录文件
路径可以用来表示文件或者文件夹所在的位置,路径是从一个文件夹开始走到另一个文件夹或者文件位置中间的这条路。把这条路经过的所有文件夹名称按顺序书写出来的结果就可以表示这条路。
路径分为绝对路径和相对路径
绝对路径:起点必须是根目录,如 /abc/def 所有绝对路径一定是以“/”作为开头的
相对路径:可以把任何一个目录作为起点,如../../abc/def 相对路径编写时不应该包含起点位置
相对目录中“..”表示上层目录
相对路径中用“.”表示当前
终端窗口里的当前目录是所有相对路径的起点,当前目录的位置是可以修改的。
pwd 命令:可以用来查看当前目录的位置
cd 命令:可以用来修改当前目录位置
ls 命令:可以用来查看一个目录的内容
3、块特殊文件
4、字符特殊文件
5、FIFO
6、套接字
7、符号链接
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) (管道或 FIFO)
S_ISLNK(m) symbolic link (符号链接)(Not in POSIX.1-1996.)
S_ISSOCK(m) socket (套接字)(Not in POSIX.1-1996.)
我们讲权限的时候,也讲过使用 ls -l 命令 也可以查看文件的类型的:
# ls -l
总用量 40
drwxr-xr-x 2 root root 4096 Mar 30 16:42 test
-rw-r--r-- 1 root root 872 Mar 30 15:04 test.c
其中第一个字符含义:
- 普通文件 (例如:/etc/passwd)
d 目录 (例如:/etc)
s 本地套接字 (例如:/dev/log)
c 字符设备 (例如:/dev/tty)
b 块设备 (例如:/dev/sr0)
l 符号链接 (例如:/dev/cdrom)
p 有名管道/FIFO (例如:/var/lib/oprofile/opd_pipe)
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>int main(int argc, char *argv[])
{struct stat sb;if (argc != 2) {fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);exit(EXIT_FAILURE);}if (stat(argv[1], &sb) == -1) {perror("stat");exit(EXIT_FAILURE);}printf("File type: ");switch (sb.st_mode & S_IFMT) {case S_IFBLK: printf("block device\n"); break;case S_IFCHR: printf("character device\n"); break;case S_IFDIR: printf("directory\n"); break;case S_IFIFO: printf("FIFO/pipe\n"); break;case S_IFLNK: printf("symlink\n"); break;case S_IFREG: printf("regular file\n"); break;case S_IFSOCK: printf("socket\n"); break;default: printf("unknown?\n"); break;}printf("I-node number: %ld\n", (long) sb.st_ino);printf("Mode: %lo (octal)\n",(unsigned long) sb.st_mode);printf("Link count: %ld\n", (long) sb.st_nlink);printf("Ownership: UID=%ld GID=%ld\n",(long) sb.st_uid, (long) sb.st_gid);printf("Preferred I/O block size: %ld bytes\n",(long) sb.st_blksize);printf("File size: %lld bytes\n",(long long) sb.st_size);printf("Blocks allocated: %lld\n",(long long) sb.st_blocks);printf("Last status change: %s", ctime(&sb.st_ctime));printf("Last file access: %s", ctime(&sb.st_atime));printf("Last file modification: %s", ctime(&sb.st_mtime));exit(EXIT_SUCCESS);
}
输出结果:
# ./a.out test.c
File type: regular file
I-node number: 2121694
Mode: 100644 (octal)
Link count: 1
Ownership: UID=0 GID=0
Preferred I/O block size: 4096 bytes
File size: 1642 bytes
Blocks allocated: 8
Last status change: Fri Mar 31 09:15:48 2017
Last file access: Fri Mar 31 09:15:53 2017
Last file modification: Fri Mar 31 09:15:48 2017
# ls -l /dev/tty
crw-rw-rw- 1 root tty 5, 0 Mar 29 16:00 /dev/tty
# stat /dev/tty文件:"/dev/tty"大小:0 块:0 IO 块:4096 字符特殊文件
设备:5h/5d Inode:4961 硬链接:1 设备类型:5,0
权限:(0666/crw-rw-rw-) Uid:( 0/ root) Gid:( 5/ tty)
最近访问:2017-03-30 16:35:58.445938548 +0800
最近更改:2017-03-29 16:00:37.867616181 +0800
最近改动:2017-03-29 16:00:37.867616181 +0800
创建时间:-
三、文件访问权限
The following flags are defined for the st_mode field:S_IFMT 0170000 bit mask for the file type bit fieldsS_IFSOCK 0140000 socketS_IFLNK 0120000 symbolic linkS_IFREG 0100000 regular fileS_IFBLK 0060000 block deviceS_IFDIR 0040000 directoryS_IFCHR 0020000 character deviceS_IFIFO 0010000 FIFOS_ISUID 0004000 set UID bitS_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 permissionS_IWUSR 00200 owner has write permissionS_IXUSR 00100 owner has execute permissionS_IRWXG 00070 mask for group permissionsS_IRGRP 00040 group has read permissionS_IWGRP 00020 group has write permissionS_IXGRP 00010 group has execute permissionS_IRWXO 00007 mask for permissions for others (not in group)S_IROTH 00004 others have read permissionS_IWOTH 00002 others have write permissionS_IXOTH 00001 others have execute permission
chmod 命令用于修改这 9 个权限位。该命令允许我们用 u 表示用户(所有者),用 g 表示组,用 o 表示其他。
四、函数 access
#include <unistd.h>
int access(const char *pathname, int mode);
1、参数解析
第一个参数:文件的路径和文件名
/* Values for the second argument to access.These may be OR'd together. */
#define R_OK 4 /* Test for read permission. */
#define W_OK 2 /* Test for write permission. */
#define X_OK 1 /* Test for execute permission. */
#define F_OK 0 /* Test for existence. */
2、函数功能:
3、返回值
4、示例说明
#include <stdio.h>
#include <unistd.h>int main (void)
{if (0 == access ("a.txt", F_OK))printf ("文件存在\n");if (0 == access ("a.txt", 4))printf ("文件可读\n");if (0 == access ("a.txt", W_OK))printf ("文件可写\n");if (0 == access ("a.txt", 1))printf ("文件可执行\n");return 0;
}
输出结果:
文件存在
文件可读
文件可写
五、函数 umask
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
1、函数功能
//创建文件 hh 查看权限:
# ls -l hh
-rw-r--r-- 1 root root 0 Mar 31 10:34 hh
查看:
# umask
0022
2、示例说明
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>int main (void)
{//使用umask函数设置屏蔽的权限mode_t old = umask (0055);//设置新的屏蔽字,返回旧的系统默认// 当前系统默认屏蔽 0055printf ("old = %o\n", old);int fd = open ("a.txt", O_RDWR | O_CREAT, 0777);if (-1 == fd)perror ("fail to open"),exit (1);//恢复系统默认的屏蔽字//对已经创建过的文件权限没有影响umask (old);close (fd);return 0;
}
输出结果:
old = 22查看 a.txt 权限,说明实际权限为 0722 (0777&~0055)屏蔽了0055
# ls -la a.txt
-rwx-w--w- 1 root root 0 Mar 31 10:25 a.txt
示例说明:
3、Linux 下的umask 指令
(1)选项
-p:输出的权限掩码可直接作为指令来执行;
-S:以符号方式输出权限掩码。
(2)示例
设置新屏蔽权限:
# umask -p 0055# umask -S 0055
u=rwx,g=w,o=w查看:
# umask
0055
六、函数 chmod 和 fchmod
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
1、参数解析
The new file permissions are specified in mode, which is a bit mask created by ORing together zero or more of the following:S_ISUID (04000) set-user-ID (set process effective user ID on execve(2))S_ISGID (02000) set-group-ID (set process effective group ID on execve(2); mandatory locking, as described in fcntl(2); take a newfile's group from parent directory, as described in chown(2) and mkdir(2))S_ISVTX (01000) sticky bit (restricted deletion flag, as described in unlink(2))S_IRUSR (00400) read by ownerS_IWUSR (00200) write by ownerS_IXUSR (00100) execute/search by owner ("search" applies for directories, and means that entries within the directory can beaccessed)S_IRGRP (00040) read by groupS_IWGRP (00020) write by groupS_IXGRP (00010) execute/search by groupS_IROTH (00004) read by othersS_IWOTH (00002) write by othersS_IXOTH (00001) execute/search by others
2、返回值
3、函数功能
4、示例说明
//示例一 chmod
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>int main (void)
{struct stat st;int res = stat ("a.txt", &st);if (-1 == res)perror ("fail to stat"), exit (1);printf ("权限是:%o\n", st.st_mode&0777);res = chmod ("a.txt", 0600);if (-1 == res)perror ("fail to chmod"), exit (1);res = stat ("a.txt", &st);if (-1 == res)perror ("fail to stat"), exit (1);printf ("权限是:%o\n", st.st_mode&0777);return 0;
}
输出结果:
权限是:644
权限是:600
//示例二 fchmod
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>int main (void)
{int fd = open ("a.txt", O_RDONLY | O_CREAT, 0644);struct stat st;int res = stat ("a.txt", &st);if (-1 == res)perror ("fail to stat"), exit (1);printf ("权限是:%o\n", st.st_mode&0777);res = fchmod (fd, 0600);if (-1 == res)perror ("fail to chmod"), exit (1);res = stat ("a.txt", &st);if (-1 == res)perror ("fail to stat"), exit (1);printf ("权限是:%o\n", st.st_mode&0777);return 0;
}
输出结果:
权限是:644
权限是:600
5、示例总结
6、Linux 下 chmod 命令
(1)修改文件 a.txt 权限为 0644
chmod 644 a.txt
查看:
# ls -l a.txt
-rw-r--r-- 1 tarena root 0 Mar 31 16:16 a.txt
七、函数 chown、fchown、lchown
#include <unistd.h>
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);
1、参数解析
2、函数功能
如若两个参数 owne r或 group 中的任意一个是 -1,则对应的 ID 不变。
3、返回值
4、示例说明
//示例一 chown
#include <stdio.h>
#include <unistd.h> int main (void)
{ //chown ("a.txt", 0, -1); chown ("a.txt", 0, 0); return 0;
}
修改前:
# ls -l a.txt
总用量 20
-rw------- 1 tarena tarena 0 Mar 31 14:24 a.txt chown ("a.txt", 0, 0); 修改后:
# ls -l a.txt
总用量 20
-rw------- 1 root root 0 Mar 31 14:24 a.txt chown ("a.txt", 0, -1); 修改后:
# ls -l a.txt
总用量 20
-rw------- 1 root tarena 0 Mar 31 14:24 a.txt
//示例二 fchown
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>int main (void)
{int fd = open ("a.txt", O_RDONLY | O_CREAT, 0644);if (-1 == fd)perror ("fail to open"), exit (1); fchown (fd , 1000, 1000);return 0;
}
修改前:
# ls -la
总用量 12
-rw-r--r-- 1 root root 0 Mar 31 15:34 a.txt修改后:
# ls -la
总用量 20
-rw-r--r-- 1 tarena tarena 0 Mar 31 15:34 a.txt
//示例三 lchown
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main (void)
{int res = lchown ("/dev/cdrom1", 1000, 1000);if (-1 == res)perror ("fail to lchown"), exit (1);return 0;
}
修改前:
# ls -l cdrom1 sr0
lrwxrwxrwx 1 root root 3 Mar 29 16:00 cdrom1 -> sr0
brw-rw---- 1 root cdrom 11, 0 Mar 29 16:00 sr0修改后:
# ls -l cdrom1 sr0
lrwxrwxrwx 1 tarena tarena 3 Mar 29 16:00 cdrom1 -> sr0
brw-rw---- 1 root cdrom 11, 0 Mar 29 16:00 sr0
5、示例总结
# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
tarena:x:1000:1000:tarena,,,:/home/tarena:/bin/bash
示例二:fchown,打开时文件描述符。
# stat /dev/cdrom1 文件:"/dev/cdrom1" -> "sr0"大小:3 块:0 IO 块:4096 符号链接
设备:5h/5d Inode:7459 硬链接:1
权限:(0777/lrwxrwxrwx) Uid:( 0/ root) Gid:( 0/ root)
最近访问:2017-03-31 15:59:53.712010169 +0800
最近更改:2017-03-29 16:00:36.411616237 +0800
最近改动:2017-03-31 15:59:47.936011311 +0800
创建时间:-
6、linux 下 chown 和 chgrp 命令
(1)将test目录所在的组由root修改为zslf组
sudo chgrp -R zslf test
查看:
root@zslf-:/mnt# ls -la test/
总用量 8
drwxr-xr-x 2 root zslf 4096 11月 24 17:20 .
drwxr-xr-x 5 root root 4096 11月 24 17:20 ..
(2)将test目录下的所有文件和子目录的属主由root改为zslf
sudo chown -R zslf.zslf test
查看:
root@zslf-virtual-machine:/mnt# ls -la test/
总用量 8
drwxr-xr-x 2 zslf root 4096 11月 24 17:20 .
drwxr-xr-x 5 root root 4096 11月 24 17:20 ..
(3)将test目录下的所有文件和子目录的属主由root改为zslf,属组有root改为zslf。
sudo chown -R zslf.zslf test
查看:
root@zslf-virtual-machine:/mnt# ls -la test/
总用量 8
drwxr-xr-x 2 zslf zslf 4096 11月 24 17:33 .
drwxr-xr-x 5 root root 4096 11月 24 17:20 ..
-rw-r--r-- 1 zslf zslf 0 11月 24 17:33 hh
八、文件长度(大小)
# ls -la
总用量 20
drwxrwxr-x 2 tarena tarena 4096 Mar 31 16:16 .
drwxrwxr-x 4 tarena tarena 4096 Mar 28 15:38 ..
-rwxr-xr-x 1 root root 7233 Mar 31 16:16 a.out
-rw-r--r-- 1 tarena root 0 Mar 31 16:16 a.txt
-rw-r--r-- 1 root root 184 Mar 31 16:15 test.c
# ls -l /dev/cdrom1
lrwxrwxrwx 1 root root 3 Apr 5 09:19 /dev/cdrom1 -> sr0
九、文件空洞
文件空洞,是由所设置的偏移量超过文件尾端,并写入了某些数据后造成的。位于文件中但没有被写过的字节都被设为 0,文件空洞不占用磁盘空间,但被计算在文件大小之内。
![](/assets/blank.gif)
# ls -l a.out
-rwxr-xr-x 1 root root 7233 Mar 31 16:16 a.out# du -h a.out
8.0K a.out
文件 a.out 长度为 7.2K,可 du 命令报告该文件所使用的磁盘空间总量为 8.0K。很明显,此文件中有很多空洞.
十、文件截断
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
1、参数解析
第一个参数:文件路径/文件描述符
2、函数功能:修改文件长度
3、返回值
4、示例说明
#include <stdio.h>
//示例一 truncate 函数
#include <unistd.h>
#include <stdlib.h>int main (void)
{int res = truncate ("a.txt", 50);if (-1 == res)perror ("fail to truncate"), exit (1);return 0;
}a.txt 为空时:
执行前:
-rw-r--r-- 1 tarena root 0 Mar 31 16:16 a.txt
执行后:
-rw-r--r-- 1 tarena root 50 Apr 5 13:14 a.txt长度截断为50,后面的数据填充为 0。a.txt 不为空时:
执行前:
-rw-r--r-- 1 tarena root 296 Apr 5 13:17 a.txt
执行后:
-rw-r--r-- 1 tarena root 50 Apr 5 13:14 a.txt长度截断为50, 后面的数据不再能访问。
//示例二 ftruncate 函数
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main (void)
{int fd = open ("a.txt", O_RDWR);if (-1 == fd)perror ("fail to open"), exit (1);int res = ftruncate (fd, 50);if (-1 == res)perror ("fail to truncate"), exit (1);return 0;
}a.txt 为空时:
执行前:
-rw-r--r-- 1 tarena root 0 Mar 31 16:16 a.txt
执行后:
-rw-r--r-- 1 tarena root 50 Apr 5 13:14 a.txt长度截断为50,后面的数据填充为 0。a.txt 不为空时:
执行前:
-rw-r--r-- 1 tarena root 296 Apr 5 13:17 a.txt
执行后:
-rw-r--r-- 1 tarena root 50 Apr 5 13:14 a.txt长度截断为50, 后面的数据不再能访问。
5、与 O_TRUNC
十一、函数 rename 和 renameat
#include <stdio.h>
int rename(const char *oldname, const char *newname);
int renameat(int oldfd,const char *oldname, int newfd, const char *newname);
1、函数功能
用于文件或目录的重命名
(2)如若oldname指的是一个目录,那么为该目录重命名。如果 newname 已存在,则它必须引用一个目录,而且该目录应当是空目录(空目录指只有.和..项)。如果 newname 存在(而且是一个新目录),则先将其删除,然后将oldname 重命名为 newname。另外,当为一个目录重命名时,newname 不能包含 oldname 作为其路径名字的路径前缀。例如,不能将 /usr/foo 重命名为 /usr/foo/testdir,因为旧名字 (/usr/foo) 是新名字的路径前缀,因而不能将其删除。
(3)如若 oldname 或 newname 引用符号链接,则处理的是符号链接本身,而不是它所引用的文件。
(4)不能对 . 和 .. 重命名。更确切的说,.和..都不能出现在 oldname 和 newname 的最后部分。
(5)作为一个特例,如果 oldname 和 newname 引用同一文件,则函数不做任何更改而成功返回。
如若 newname 已经存在,则调用进程对它需要有写权限。另外,调用进程将删除 oldname 目录项,并可能要创建 newname 目录项,所以它需要对包含的 oldname 及包含 newname 的目录具有写和执行权限。
除了当 oldname 或 newname 指向相对路径名时,其他情况下 renameat 函数与 rename 函数功能相同。如果 oldname 参数指定了相对路径,就相对于 oldfd 参数引用的目录来计算 oldname。类似的,如果 oldname 参数指定了相对路径,就相对于newfd引用的目录来计算 newname。oldfd 或 newfd 参数都能设置成 AT_FDCWD,此时相对于当前目录来计算相应的路径名。
2、返回值
3、示例说明
#include <stdio.h>
#include <stdlib.h>int main (void)
{rename ("a.txt", "b.txt");return 0;
}
4、Linux 下的 mv 命令
mv命令用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中。
(1)选项
--backup=<备份模式>:若需覆盖文件,则覆盖前先行备份;
-b:当文件存在时,覆盖前,为其创建一个备份;
-f:若目标文件或目录与现有的文件或目录重复,则直接覆盖现有的文件或目录;
-i:交互式操作,覆盖前先行询问用户,如果源文件与目标文件或目标目录中的文件同名,则询问用户是否覆盖目标文件。用户输入”y”,表示将覆盖目标文件;输入”n”,表示取消对源文件的移动。这样可以避免误将文件覆盖。
--strip-trailing-slashes:删除源文件中的斜杠“/”;
-S<后缀>:为备份文件指定后缀,而不使用默认的后缀;
--target-directory=<目录>:指定源文件要移动到目标目录;
-u:当源文件比目标文件新或者目标文件不存在时,才执行移动操作。
(2)示例
将文件ex3改名为new1
mv ex3 new1
十二、函数 mkdir、mkdirat和 rmdir
#include <sys/stat.h>
int mkdir (const char *pathname, mode_t mode);
int mkdirat(int dirfd, const char *pathname, mode_t mode);
1、函数功能
2、返回值
3、mode 方式
S_IRWXU 00700权限,代表该文件所有者拥有读,写和执行操作的权限
S_IRUSR(S_IREAD) 00400权限,代表该文件所有者拥有可读的权限
S_IWUSR(S_IWRITE) 00200权限,代表该文件所有者拥有可写的权限
S_IXUSR(S_IEXEC) 00100权限,代表该文件所有者拥有执行的权限
S_IRWXG 00070权限,代表该文件用户组拥有读,写和执行操作的权限
S_IRGRP 00040权限,代表该文件用户组拥有可读的权限
S_IWGRP 00020权限,代表该文件用户组拥有可写的权限
S_IXGRP 00010权限,代表该文件用户组拥有执行的权限
S_IRWXO 00007权限,代表其他用户拥有读,写和执行操作的权限
S_IROTH 00004权限,代表其他用户拥有可读的权限
S_IWOTH 00002权限,代表其他用户拥有可写的权限
S_IXOTH 00001权限,代表其他用户拥有执行的权限
4、示例说明
#include <stdio.h>
#include <stdlib.h>int main (void)
{mkdir ("test", 0755);return 0;
}
5、Linux 下的 mkdir 命令
(1)选项
-Z:设置安全上下文,当使用SELinux时有效;
-m <目标属性>或--mode<目标属性>建立目录的同时设置目录的权限;
-p或--parents 若所要建立目录的上层目录目前尚未建立,则会一并建立上层目录;
--version 显示版本信息。
(2)示例
在目录/usr/meng下建立子目录test,并且只有文件主有读、写和执行权限,其他人无权访问
mkdir -m 700 /usr/meng/test在当前目录中建立bin和bin下的os_1目录,权限设置为文件主可读、写、执行,同组用户可读和执行,其他用户无权访问
mkdir -p-m 750 bin/os_1
6、函数 rmdir
#include <unistd.h>
int rmdir( const char *pathname );
返回值:若成功则返回0,若出错则返回-1
(1)示例
#include <stdio.h>
#include <stdlib.h>int main (void)
{rmdir ("test");return 0;
}
7、Linux 下的 rmdir 命令
(1)选项
-p或--parents:删除指定目录后,若该目录的上层目录已变成空目录,则将其一并删除;
--ignore-fail-on-non-empty:此选项使rmdir命令忽略由于删除非空目录时导致的错误信息;
-v或-verboes:显示命令的详细执行过程;
--help:显示命令的帮助信息;
--version:显示命令的版本信息。
(2)示例
删除子目录os_1和其父目录bin
rmdir -p bin/os_1
8、Linux 下的 rm 命令
(1)选项
-d:直接把欲删除的目录的硬连接数据删除成0,删除该目录;
-f:强制删除文件或目录;
-i:删除已有文件或目录之前先询问用户;
-r或-R:递归处理,将指定目录下的所有文件与子目录一并处理;
--preserve-root:不对根目录进行递归操作;
-v:显示指令的详细执行过程。
(2)示例
删除 test 目录下除隐含文件外的所有文件和子目录
# rm -r test
(3)说明
不过使用 rm 是很危险的,删除的东西是无法恢复。有时养成好的习惯使用 -i 选项删除前先询问用户一下也不错。
十三、读目录
1、opendir 函数
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
(1)函数功能
(2)返回值
2、readdir 函数
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
(1)函数功能
(2)结构体参数
struct dirent {ino_t d_ino; /* inode number */ //i节点的编号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 */ //文件名};
3、closedir 函数
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
(1)函数功能
主要用于关闭参数指定的目录
(2)示例说明
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>int main (void)
{DIR *dir = opendir ("code");if (NULL == dir)perror ("fail to opendir"), exit (1);struct dirent *ent;while (ent = readdir (dir))printf ("文件名为:%s\n", ent->d_name);closedir (dir);return 0;
}
输出结果:
文件名为:test
文件名为:.
文件名为:..
十四、函数 chdir、fchdir 和 getcwd
1、chdir、fchdir
#include <unistd.h>
int chdir(const char *path);
int fchdir(int fd);
(1)函数功能
(2)返回值
(3)示例说明
//示例一 chdir
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main (void)
{if (-1 == chdir ("/tmp"))perror ("fail to chdir"), exit (1);return 0;
}
//示例二 fchdir
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main (void)
{int fd = open ("/tmp", O_RDONLY); if (-1 == fchdir (fd))perror ("fail to fchdir"), exit (1);char buf[100];if (getcwd(buf, 100) == NULL)perror ("fail to getcwd"), exit (1);printf("cwd = %s\n", buf);return 0;
}
输出结果:
cwd = /tmp
(4)示例总结
2、函数 getcwd
#include <unistd.h>
char *getcwd(char *buf, size_t size);
(1)函数功能
(2)返回值
(3)示例说明
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main (void)
{if (chdir("/usr/bin/") < 0)perror ("chdir failed"), exit (1);char buf[100];if (getcwd(buf, 100) == NULL)perror ("fail to getcwd"), exit (1);printf("cwd = %s\n", buf);return0;
}
输出结果:
cwd = /usr/bin
(4)Linux 下的 pwd 命令
十五、未讲部分:
UNIX再学习 -- 文件和目录相关推荐
- UNIX再学习 -- 文件I/O
上一篇讲完文件描述符,接下来进入正题,文件的处理函数. 一.函数 open 详细内容,可自行 man creat 查看 #include <sys/types.h> #include &l ...
- UNIX再学习 -- 文件描述符
在 UNIX/Linux 系统中,一切皆文件,这句话想必都有听过.对于文件的操作几乎适用于所有的设备,这也就看出了文件操作的重要性了.在C语言再学习部分有讲过标准I/O文件操作,参看:C语言再学习 - ...
- UNIX再学习 -- 守护进程(转)
参看:守护进程 一.什么是守护进程 守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程.它是一个生存期较长的进程,通常独立于控制 ...
- UNIX再学习 -- 用户 ID 和组 ID
用户 ID和组 ID 的内容已经在好几章中出现过了.之前都没有讲到,现在放到一起总结. 一.用户 ID 和 组 ID 回顾 1.我们在APUE 第 4.6.8 章,都有涉及到. 其中我们用到的地方: ...
- UNIX再学习 -- 信号
终于讲到信号部分,很多比较重要的应用程序都需处理信号.第 9 章需要先了解信号机制再看,所以先跳过不讲.现在开始详解信号. 一.信号概念 信号是提供异步事件处理机制的软件中断. 这些异步事件可能来自硬 ...
- UNIX再学习 -- exec 函数族
我们在讲,文件I/O的时候,简单提到过 exec 函数,讲到 vfork 的时候,也有用到.下面我们来详细介绍下它. 参看:UNIX再学习 -- 文件I/O 参看:UNIX再学习 -- 函数 for ...
- UNIX再学习 -- 记录锁
APUE第 3 章,参看:UNIX再学习 -- 文件I/O fcntl 函数它的记录锁功能我们当时没讲.接下来就详细说明下. 一.读写冲突 1.如果两个或两个以上的进程同时向一个文件的某个特定的区域 ...
- UNIX再学习 -- 标准I/O
这部分之前有所总结: 参看:C语言再学习 -- 文件 参看:C语言再学习 -- 输入/输出 参看:UNIX再学习 -- 文件描述符 对比:UNIX再学习 -- 文件I/O 一.流 文件I/O中,所有的 ...
- UNIX再学习 -- 进程间通信之管道
一.进程间通信概念 首先,需要了解一下什么是进程间通信. 进程之间的相互通信的技术,称为进程间通信(InterProcess Communication,IPC). 下图列出 4 种实现所支持的不同形 ...
最新文章
- 微信公众平台开发(45)食物营养及热量查询
- mysql存储过程迭代自己获取所有子孙
- 锐捷校园网环境下使用虚拟机上网
- RN开发关闭所有黄色警告弹出(console.warn())
- TCP和UDP区别?如何改进TCP
- 2022年最新前端面试题(大前端时代来临卷起来吧小伙子们..持续维护走到哪记到哪)
- avx2指令集对php有用吗,AVX2指令集的作用
- Ajax 请求的http头信息特点 x-requested-with
- turtle库使用——漫天繁星+万花筒绘制
- 异步协议与同步协议:面向字符的协议BSC协议
- 格力(GREE)家用移动空调免安装一体机空调KY-23NK 清灰拆装教程
- 发生系统错误 5。拒绝访问。
- 计算机系班级未来展望,大学生班长对班级未来的展望.doc
- 不换门可以改开门的方向吗_不换门可以改开门的方向吗?
- Android FOTA 升级流程
- 最新版泛域名证书申请
- 32.构造ICMP请求包进行路由跟踪
- 中山一院——新一代的智慧医院建设,以流量分析为抓手,提升用户体验
- ios沙箱软件_iOS应用软件沙盒sandbox相关知识(整理)
- dpdk-18.11网卡多队列RSS设置