为了能解释清楚inode我们先简单了解一下文件系统:
超级块:存放文件系统本身的结构信息
inode:存放文件属性,如文件大小,所有者,最近修改时间等
数据区:存放文件内容
事实上,真正找到磁盘上文件的并不是文件名,而是inode。
inode
(1)查看每一个目录下每个文件的inode号
[a@localhost ~]$ ls -i
270062 \ 269732 Desktop 269733 Downloads 269738 Pictures 269735 Public 269796 test.txt
260610 bb 269736 Documents 269737 Music 401249 process 269734 Templates 269739 Videos
[a@localhost ~]$
(2)可以使用stat指令查看对应文件的inode
[a@localhost ~]$ stat test.txt
File: `test.txt'
Size: 50 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 269796 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 500/ a) Gid: ( 500/ a)
Access: 2018-03-07 15:51:25.028622769 -0500
Modify: 2018-03-07 15:51:25.029622766 -0500
Change: 2018-03-07 15:51:25.029622766 -0500
[a@localhost ~]$
相关名词:
Size 文件所占的字节数
Block 文件数据的所占的块
Links 硬连接数
Uid 文件拥有者
Gid 文件的所属用户组
Access 最后访问时间
Modify 文件内容最后修改时间
Change 属性最后修改时间
(3)查看硬盘上inode总数和适用情况
[a@localhost ~]$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda2 1164592 98397 1066195 9% /
tmpfs 125551 5 125546 1% /dev/shm
/dev/sda1 76912 38 76874 1% /boot
(4)查看硬盘上块的总数和使用情况
[a@localhost ~]$ df -l
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 18339256 2742812 14664860 16% /
tmpfs 502204 80 502124 1% /dev/shm
/dev/sda1 297485 34634 247491 13% /boot
硬链接
每个文件可以建立一个或者多个硬链接,可以达到防误删的功能,当删除了源文件时,可以通过硬链接文件来访问文件数据。
指令ln用来创建硬链接文件:
[a@localhost ~]$ touch abc
[a@localhost ~]$ ln abc def
[a@localhost ~]$ ls -li abc def
269646 -rw-rw-r--. 2 a a 0 Mar 16 16:52 abc
269646 -rw-rw-r--. 2 a a 0 Mar 16 16:52 def
[a@localhost ~]$
abc和def的链接状态完全相同,它们被称为指向文件的硬链接。inode 263466的硬链接数为2.
删除文件:在目录中将对应的记录删除;将硬链接数-1,如果为0.则将对应的磁盘释放。
引用计数
真正找到磁盘上文件的并不是文件名,而是inode。可以让多个文件名对应同一个inode,是一种引用计数的运用。
[a@localhost ~]$ stat file
File: `file'
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 802h/2050d Inode: 269747 Links: 2
Access: (0777/drwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2018-01-21 16:37:00.221270279 -0500
Modify: 2018-01-21 16:18:04.719270233 -0500
Change: 2018-01-21 16:18:04.719270233 -0500
[a@localhost ~]$
Links的初始值是1,之前我们为它创建了一个硬链接,所以加1此时值为2,当删除一个硬链接文件,它的值就会减1.
硬链接的限制:
(1)不能跨越文件系统
(2)不允许普通用户对目录做硬链接。
[a@localhost file]$ ll
total 4
drwxrwxr-x. 2 a a 4096 Apr 13 11:05 dir
----------. 1 a a 0 Apr 13 11:00 file1
-rw-rw-r--. 1 a a 0 Apr 13 11:00 file2
[a@localhost file]$ ln dir h_dir
ln: `dir': hard link not allowed for directory
软链接
软连接又叫做符号连接,类似于Windows系统的快捷方式。
与硬链接不同,它没有引用计数,软链接是通过名字引用另外一个文件。
创建软连接:用ln指令的-s选项
软链接有自己的inode
[a@localhost file]$ ln -s file2 s_file2
[a@localhost file]$ ll -li
total 4
401803 drwxrwxr-x. 2 a a 4096 Apr 13 11:05 dir
401342 ----------. 1 a a 0 Apr 13 11:00 file1
401802 -rw-rw-r--. 1 a a 0 Apr 13 11:00 file2
401804 lrwxrwxrwx. 1 a a 5 Apr 13 11:07 s_file2 -> file2
可以理解为软链接s_file2中放的是file2的路径。
[a@localhost file]$ vim file2
[a@localhost file]$ cat file2
aaaaaa
[a@localhost file]$ cat s_file2
aaaaaa
[a@localhost file]$
删除软链接:
[a@localhost file]$ rm -rf s_file2
软链接的特点:
(1)可以对目录创建软链接
(2)可以跨文件系统
(3)可以对不存在的文件创建软链接
库
库就是别人写好的一些代码,我们可以拿来复用以提高开发效率。
库的本质是一种二进制的文本文件,可以被操作载入内存执行。
静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
命名方式:”libxxx.a”,库名前加”lib”,后缀用”.a”,”xxx”为静态库名。
优点:
(1)方便移植(程序运行时与静态库没有瓜葛)
(2)代码装载速度快(不需要动态链接)
缺点:
(1)静态库在程序编译时会被链接到目标文件中,可执行程序体积大
(2)修改起来麻烦,不方便维护
安装glibc-static:
yum install glibc-static
使用静态库:
gcc -o main main.c -static -lmytest -L.
static 表示程序是静态链接
-l[name]指定静态库
-L[PATH]指定静态库的路径,’.’表示当前路径
例子:
[a@localhost lib]$ gcc -c add.c -o add.o
[a@localhost lib]$ gcc -c sub.c -o sub.o
//生成静态库
[a@localhost lib]$ ar -rc libmymath.a add.o sub.o
//查看静态库中的目录列表
[a@localhost lib]$ ar -tv libmymath.a
rw-rw-r-- 500/500 1240 Mar 17 09:47 2018 add.o
rw-rw-r-- 500/500 1240 Mar 17 09:49 2018 sub.o
//-L 指定库目录 -l指定库名
[a@localhost lib]$ gcc main.c -L -lmymath
[a@localhost lib]$ ls
add.h libmymath.a main main.c sub.h
[a@localhost lib]$ ./main
-10,30
动态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
这个动态库在内存中只有一份,通过共享映射区映射给每一个调用这个库的进程,直到最后一个调用这个库的进程结束,内存中的动态库才撤出内存,从而避免了静态库的空间浪费。
命名方式:前缀相同,为”lib”,后缀变为”.so”,所以为”libmymath.so”.
优点:
(1)节省空间,实现资源共享。(通过引用计数来统计当前连接的执行程序,链接为0就释放动态库的内存。)
(2)适用于大规模的软件开发,使开发过程独立,耦合度小。 (3)不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数。
(4)将一些程序的升级变得简单,甚至可以真正做到链接载入完全由程序员在代码中控制。
缺点:
(1)使用动态链接库的应用程序不是自完备的,它依赖于DLL模块也要存在。 (2)速度比静态链接慢。
(3)当某个模块更新后,如果新模块与旧模块不兼容,那么那些需要该模块才能运行的软件,通通撕掉。
//shared:表示生成共享库格式
//fPIC:产生与位置无关代码
[a@localhost lib_so]$ gcc -fPIC -c sub.c add.c
[a@localhost lib_so]$ ll
total 24
-rw-rw-r--. 1 a a 56 Apr 13 12:07 add.c
-rw-rw-r--. 1 a a 82 Apr 13 12:07 add.h
-rw-rw-r--. 1 a a 1240 Apr 13 12:08 add.o
-rw-rw-r--. 1 a a 56 Apr 13 12:07 sub.c
-rw-rw-r--. 1 a a 82 Apr 13 12:07 sub.h
-rw-rw-r--. 1 a a 1240 Apr 13 12:08 sub.o
//生成动态库
[a@localhost lib_so]$ gcc -shared -o libmymath.so *.o
[a@localhost lib_so]$ ls
add.c add.h add.o libmymath.so sub.c sub.h sub.o
[a@localhost lib_so]$ ls
add.c add.h add.o libmymath.so sub.c sub.h sub.o
[a@localhost lib_so]$ gcc -fPIC -c sub.c add.c
使用动态库:
[a@localhost test]$ gcc -o main main.c -L. -lmymath
[a@localhost test]$ ls
add.h libmymath.so main main.c sub.h
[a@localhost test]$ ./main
./main: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory
[a@localhost test]$ export LD_LIBRARY_PATH=.
[a@localhost test]$ ldd main
linux-vdso.so.1 => (0x00007fff079ff000)
libmymath.so => ./libmymath.so (0x00007fef3bc13000)
libc.so.6 => /lib64/libc.so.6 (0x0000003775e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003775600000)
[a@localhost test]$ ls
add.h libmymath.so main main.c sub.h
[a@localhost test]$ ./main
-10,30
[a@localhost test]$
外部库
系统中其实有很多库,它们通常由一组相关联的用来完成某项常见工作的函数构成。
[a@localhost test]$ gcc -o main main.c -lm
[a@localhost test]$ ls
add.h libmymath.so main main.c sub.h
[a@localhost test]$ ./main
The cubed is 8.000000
[a@localhost test]$ cat main.c
#include
#include
int main()
{
double x = pow(2.0,3.0);
printf("The cubed is %f\n",x);
return 0;
}