目录
- /dev 目录是干什么的?
- /proc 和 /sys 目录是干什么的?
- udev 这个软件是干什么用的?
- 目录映射是临时性的,还是永久性的?
- 命令行里大括号 “{}” 的作用是什么?
- 设置目录权限为 “1777” 表示什么?
- ls -l 后,第一列第一个字符表示什么?第三列和第四列又表示什么?
- exec 命令的特点是什么?
- 其他函数库文件都已 lib 开头,那么 ld 开头的函数库文件有什么不同呢?
- ldd /bin/cat 的结果如何解析?
- 是 ldd 命令表示共享库文件,还是 ld-linux.so.2 显示出来?
- ld-linux.so.2 是哪个平台的名称?其他平台也叫这个?
- ldd 命令的本质是什么?
/dev 目录是干什么的?
该目录用于存放各种设备文件。
Linux 下都是通过文件的形式来进行设备访问的,设备文件的类型包括块设备、字节设备、虚拟设备等。
/proc 和 /sys 目录是干什么的?
这两个目录是用于存放和内核数据相关的内容,通过内核自身的虚拟文件系统将内核中的信息以文件的形式体现出来,可以通过这些文件与内核进行交互。
udev 这个软件是干什么用的?
udev 软件包中含有一组用于动态创建设备文件的程序,可以将这些程序一并称为 Udev 系统。
大多数 Linux 系统会使用 Udev 系统来管理 /dev 目录中的设备文件,Udev 系统会自动检测计算机丙且生成设备文件,Udev 系统还具有热插拔设备的管理能力,能够根据设备的实际使用情况来进行动态的创建和删除设备文件,几大的节省管理设备文件的难度。
目录映射是临时性的,还是永久性的?
被映射的源目录和映射目录内容上保持一致,对他们中的任何一方目录内的改动将直接导致另一方同样的修改。
与链接文件处理方式不同,源目录和映射目录都必须是实际的目录而不是链接文件,目录映射并不依赖源目录的存在位置,即使在简历好目录映射后,改变源目录的名称或者位置都不会影响到映射目录的内容。
命令行里大括号 "{}" 的作用是什么?
表示将需要处理的字幕中相同部分进行合并,不同的内容和大括号内的字符组合,类似数学上的合并同类项。
例如: mkdir -pv /var/{lock, log, mail, run, spool}
等于:mkdir -pv /var/lock /var/log /var/mail /var/run /var/spool
还有一种使用方法
例如:mkdir -pv /usr/{, local/}share/man/man{1..8}
这个命令会创建如下的目录:
/usr/share/man/man1
/usr/share/man/man2
一直到 /usr/share/man/man8
然后
/usr/local/share/man/man1
/usr/local/share/man/man2
一直到 /usr/share/man/man8
设置目录权限为 "1777" 表示什么?
后三位是权限模式,第一位是粘贴位,设置为 1 后,可以使用户不能从中删除其他用户创建的文件或者目录。
ls -l 后,第一列第一个字符表示什么?第三列和第四列又表示什么?
第一列用 10 个自负来表示文件的类型以及访问权限。
其中第一个自负代表这个文件的类型。
-: 表示一般文件
d:表示目录
l:表示链接文件
c:表示字符设备文件
b:表示块设备文件
p:表示管道文件
第三列表示文件的所属用户,第四列表示的则是该文件所属组的名称。
exec 命令的特点是什么?
与直接运行程序的方式不同,exec 将使运行的程序覆盖调用他的程序,即在 bash 下运行 exec,bash 将推出运行。
而 exec 所执行的程序将替代 bash 执行。
具体过程如下:
当前运行了一个 bash ,称为 bash1 ,运行状态如下:
bash1
然后在其上直接运行 bash 命令,刚运行的 bash 称为 bash2 ,这时实际上是有两个bash 在运行的,而当前是由 bash2 来与用户交互,运行状态如下:
bash1 -> bash2
这时使用 ls 命令:
bash1 -> bash2 -> ls
而如果使用 exec ls 来运行 ls 命令,将会使用 ls 命令来替代 bash2 运行,此时的运行状态如下:
bash1 -> ls
ls 命令执行完成后,将会退回到 bash1 上:
bash1
需要注意的,如果你直接就在 bash1 下使用 exec 来执行命令,那么执行完毕后,终端会自动关闭,因为已经没有 shell 了。
其他函数库文件都已 lib 开头,那么 ld 开头的函数库文件有什么不同呢?
Glibc 只能黄的文件中,有一个特殊的函数库文件,就是 ld-linux.so.2,这个文件在不同的平台上会有不一样的名字,但是名字都以 ld 开头,这一点非常特别。
这以 ld 开头的共享函数库文件的特别之处在于,他是用来寻找其他函数库文件的函数库。
使用 ldd 明林过去查看一个动态链接的文件,其链接的共享函数库中一定会有一个 ld 开头的文件,这个函数库文件的作用就是用来帮助该文件在运行期间想寻找其他函数库文件。
ldd /bin/cat 的结果如何解析?
使用这个命令后,显示的结果如下:
linux-gate.so.1 => (0xb77d800)
libc.so.6 => /lib/libc.so.6 (0xb7662000)
/lib/ld-linux.so.2 (0xb77d9000)
对于每行最后十六进制的地址我们可以不用理会,它代表的是各个函数库文件的入口地址。
其中 linux-gate.so.1 不是实际的函数库文件,它是虚拟的函数库文件,用于和 Linux 内核进行接口。
libc.so.6 => /lib/libc.so.6
表达的含义就是 cat 命令在运行的时候需要使用 libc.so.6 这个共享函数库,而这个函数库文件就位于 /lib/libc.so.6
那么 libc.so.6 这个文件是如何被系统找到,在 ldd /bin/cat 命令运行的时候又是如何发现该文件的存放位置的呢?
要回答这个问题,要先来看ldd 命令显示内容的最后一行:/lib/ld-linux.so.2 这个函数库并没有和 libc.so.6 使用一样的表示方式,而是直接就定位到 /lib/ld-linux.so.2 上,而正是这个函数库,帮 cat 命令找到所需要的其他函数库文件,比如 libc.so.6
是 ldd 命令表示共享库文件,还是 ld-linux.so.2 显示出来?
如果 ld-linux.so.2 寻找运行时需要的函数库文件,但是谁来查找 ld-linux.so.2 这个文件呢?
答案是只要直接将该文件的路径写在程序中,就可以不用寻找了,这也是为什么 GCC 的配置文件中会专门处理该文件的原因。只要为程序提供了 ld=linux.so.2 的路径,那么其他的共享函数库文件如何寻找就由该函数库的功能来决定了。
这样卡莱 cat 命令需要用到其他函数库时,首先会将需要的函数库名称告诉给 ld-linux.so.2 听,如果需要 libc.so.6 就由该函数库根据相关的设置来进行查询,这些设置包括 lD_LIBRAY_PATH 环境变量的设置,/etc/ld.so.conf 中的配置和 ld-linux.so.2 自己的默认搜索路径等。
所以并非 ldd 命令将 cat 明林龟缩依赖的函数库显示出来,而是 cat 命令自己显示的结果,cat 命令也是因为使用 ld-linux.so.2 才能显示需要的函数库所存放的目录为止,可以使用如下命令来验证:
/lib/ld-linux.so.2 --list /bin/cat
其显示的效果将和使用 ldd /bin/cat
是一样的。
所以,cat 命令功能上只依赖于 libc.so.6 这个函数库,而实际上,要正常的运行 ld-linux.so.2 也是不能缺少的,但是如果静态编译的程序,就不需要 ld-linux.so.2 来参与运行了。
ld-linux.so.2 是哪个平台的名称?其他平台也叫这个?
ld-linux.so.2 是 x86 平台上的名称,在不同的平台上名称会有所不同,如在 MIPS 平台上就是 ld.so.1 但是都是以 ld 开头的名字。
ldd 命令的本质是什么?
ldd 命令用于将指定命令所依赖的共享函数库显示出来。
ldd 命令本身是一个脚本文件,以办事hi用 bash 来解释执行。
该命令虽然功能上表现为 显示指定的想和程序所依赖的共享函数库,但是实际上该命令是通过设置环境变量的方式来使得程序运行在一种特殊的状态下面的,该状态将不会运行命令的实际功能,而是显示其所依赖的函数库,通过下面的命令来验证:
LD_TRACE_LOADED_OBJECTS=1 /bin/cat
运行结果和 ldd /bincat
命令结果是一致的。
依赖 Glibc 的任何程序在环境变量 LD_TRACE_LOADED_OBJECTS 不为空的情况下,都会显示其所依赖的函数库文件以及函数库锁在目录,所以该环境变量设置为 0 也一样是显示依赖库的结果。
想再进一步了解为何设置该环境变量就会显示依赖函数库,就需要去了解机遇 Glibc 的 ld-linux.so.2 函数库,使用下面的命令也可以显示命令依赖的函数库。
/lib/ld-linux.so.2 --list /bin/cat
动态链接的程序会使用该函数库来查找依赖的其他函数库文件,该函数库中的函数在检测到有 LD_TRACE_LOADED_OBJECTS 不为空的时候将显示依赖的函数库以及存放为止,而不运行程序,这点可以通过下面的命令来验证:
LD_TRACE_LOADED_OBJECTS=1 /sbin/insmod.static
该命令的执行结果与直接运行 /sbin/insmod.static
一样,不受环境变量设置的影响,因为 /sbin/insmod.static
是一个静态编译的程序文件,运行时没有 ld-linux.so.2 参与,因此不会对环境变量 LD_TRACE_LOADED_OBJECTS
做出响应。
换句话说,如果想对这个环境变量做出响应,就需要该程序是利用共享函数库进行动态编译的程序,静态编译的程序是不会对该环境变量产生反应的。