一、探寻文件信息的file命令
file命令可以识别出文件的类型和编码格式
1、查看文件类型
#不加任何选项,直接查看0.sh文件
[linson@www ~]$ file 0.sh
0.sh: ASCII text
-b 选项:使file命令的输出不出现文件名,只显示文件格式以及编码
[linson@www ~]$ file -b test.sh
Bourne-Again shell script, ASCII text executable
-i 选项:可以输出文件的MIME类型字符串(Multipurpose Internet Mail Extensions,称为多用途互联网邮件扩展类型。
常见的类型包括:
text/plain:普通文件。
text/html:HTML文本。
application/pdf:PDF文档。
application/msword:Word文档
image/png:PNG图片
image/jpeg:JPEG图片
application/x-tar:TAR文件
application/x-gzip:GZIP文件
2、设置输出分隔符
file命令的输出格式是:文件名:文件类型和编码格式
如果希望将中间的分隔符由冒号(:)改成其他符号,则可以使用-F选项来实现。
[linson@www ~]$ file test.sh
test.sh: Bourne-Again shell script, ASCII text executable
[linson@www ~]$ file -F "=>" test.sh
test.sh=> Bourne-Again shell script, ASCII text executable
在一些自动化文件分析的脚本中,开发者为了避免分隔符和普通字符重复而造成误解析的情况,通常是会手工调整间隔符的。
3、查看软链接文件
[linson@www ~]$ ln -s test.sh test_s.sh
[linson@www ~]$ file test_s.sh
test_s.sh: symbolic link to `test.sh'
[linson@www ~]$ file -L test_s.sh
test_s.sh: Bourne-Again shell script, ASCII text executable
如果通过file命令直接查看软链接文件,则查看的就是软链接文件本身的信息。
如果使用-L选项来查看软链接文件,则查看的是软链接指向的目标文件的信息。
4、按照清单去工作
如果我闪需要用file命令查看大量文件的类型信息,恰好这些文件的名称都被存储在了一个文本文件中,那么-f选项就派上用场。
-f 选项指定文本文件,file命令会乘乘地去逐个查看每一个文件的类型信息。
[linson@www ~]$ cat poetry_list.txt
/home/linson/test.sh
/home/linson/declare.txt
/home/linson/readtime.sh
/home/linson/test_s.sh
/home/linson/tetttt.sh
[linson@www ~]$ file -f poetry_list.txt
/home/linson/test.sh: Bourne-Again shell script, ASCII text executable
/home/linson/declare.txt: ASCII text, with very long lines
/home/linson/readtime.sh: Bourne-Again shell script, ASCII text executable
/home/linson/test_s.sh: symbolic link to `test.sh' #指向test.sh的软链接test_s.sh
/home/linson/tetttt.sh: cannot open (No such file or directory) #一个明显不存在的文件
-z 选项,想说爱你不容易
第一轮试验开始,先来试验“一个未经压缩的tar包”
[linson@www ~]$ tar -cvf inputfile.tar inputfile1.sh inputfile.sh
inputfile1.sh
inputfile.sh
[linson@www ~]$ file -z inputfile.tar
inputfile.tar: POSIX tar archive (GNU)
file只是看出inputfile.tar是一个tar包,并没有深入到tar包内部,第一轮试验宣告失败。
第二轮试验,看一个经过gzip压缩过的tar包情况如何?
[linson@www ~]$ tar -zcvf inputfile.tar.gz inputfile1.sh inputfile.sh test_s.sh
inputfile1.sh
inputfile.sh
test_s.sh
[linson@www ~]$ file -z inputfile.tar.gz
inputfile.tar.gz: POSIX tar archive (GNU) (gzip compressed data, from Unix, last modified: Thu Jul 27 20:45:42 2017)
输出的信息稍微丰富一些,但还是停留在tar包的文件类型的层面,仍然没有窥探到里面的文件,第二轮实验宣告失败。
第三轮试验,那bzip2压缩的tar包是否OK
[linson@www ~]$ tar -jcvf inputfile.tar.bz2 inputfile1.sh inputfile.sh
inputfile1.sh
inputfile.sh
[linson@www ~]$ file -z inputfile.tar.bz2
inputfile.tar.bz2: POSIX tar archive (GNU) (bzip2 compressed data, block size = 900k)
试验仍然失败
第四轮试验,制作一个只包含一个文件的bz2文件
[linson@www ~]$ bzip2 -c inputfile.sh > inputfile.bz2
[linson@www ~]$ file -z inputfile.bz2
inputfile.bz2: Bourne-Again shell script, ASCII text executable (bzip2 compressed data, block size = 900k)
第五轮试验,制作一个仅包含1个文件的gz文件
[linson@www ~]$ gzip -c inputfile.sh > inputfile.gz
[linson@www ~]$ file -z inputfile.gz
inputfile.gz: Bourne-Again shell script, ASCII text executable (gzip compressed data, was "inputfile.sh", from Unix, last modified: Tue Jul 4 21:54:13 2017)
[linson@www ~]$ file inputfile.gz
inputfile.gz: gzip compressed data, was "inputfile.sh", from Unix, last modified: Tue Jul 4 21:54:13 2017
-z选项只支持对gzip包内部文件的窥探,而对于tar、tar.gz、tar.bz2和bz2包全部都不支持。
二、ln连接世界
ln是一个很神奇的命令,它可以创建一个文件的影子,也可以通过一个通道进入另一个地方。其实,所有的这些把戏都是通过软链接和硬链接来实现的。
1、链接也分软硬
软链接,全称是软链接文件,英文叫作 symbolic link。这类文件其实非常类似于Windows里的快捷方式,这个软链接文件(假设叫A)的内容,其实是另外一个文件(假设叫B)的路径和名称,当打开A文件时,实际上系统会根据其内容找到并打开B文件。
硬链接,全称是硬链接文件,英文叫作hard link。这类文件比较特殊,这类文件(假设叫A)会拥有自己的inode节点和名称,其inode会指向文件内容所在的数据块。与此同时,该文件内容所在的数据块的引用计数会加1。当此数据块的引用计数大于等于2时,则表示有多个文件同时指向了这一数据块。一个文件修改,多个文件都会生效。当删除其中某个文件时,对另一个文件不会有影响,仅仅是数据块的引用计数减1.当引用计数为0时,则系统才会清除此数据块。
2、建立属于你的第一个硬链接
硬盘上已经有一个文件,叫作source.txt,针对这个文件建一个硬链接文件,名字叫作hardsource.txt
[linson@www ~]$ ls -l source.txt
-rw-rw-r--. 1 linson linson 14 7月 27 21:11 source.txt
[linson@www ~]$ ln source.txt hardsource.txt
[linson@www ~]$ ls -il source.txt hardsource.txt
126 -rw-rw-r--. 2 linson linson 14 7月 27 21:11 hardsource.txt
126 -rw-rw-r--. 2 linson linson 14 7月 27 21:11 source.txt
建立硬链接的命令格式是:
$ ln 源文件名称 硬链接文件名称
首先,用ln source.txt hardsource.txt建立了一个source.txt文件的硬链接文件。然后,用ls -il命令查看了文件的信息。其中,-i选项表示列出每个文件的inode节点ID,可以发现source.txt和hardsource.txt的inode号完全一致,都是126,这就说明它们都指向同一个数据块。
有一点需要注意,硬链接不允许跨分区来建立,也不允许跨文件系统来建立,即使是同一类型的文件系统也不行,这主要是受限于inode指向数据块的名字空间。所以,记住,硬链接只能在同一个分区内建立。
3、建立属于你的第一个软链接
建立一个source.txt文件的软链接,名字叫作softsource.txt
[linson@www ~]$ ln -s source.txt softsource.txt
[linson@www ~]$ ls -il source.txt softsource.txt
114 lrwxrwxrwx. 1 linson linson 10 7月 27 21:40 softsource.txt -> source.txt
126 -rw-rw-r--. 2 linson linson 14 7月 27 21:11 source.txt
建立软链接也是使用ln命令,但是必须加上-s选项,即--symbolic选项,建立软链接的命令格式为:
ln -s 源文件名称 软链接文件名称
使用li -il命令查看,发现软链接文件softsource.txt和源文件source.txt的inode号是不一样的,这说明它们完全指向两个不同的数据块。而且,细心的朋友能够观察到软链接文件的权限栏首字符为l(L的小写字母),这也是软链接文件区别于普通文件的地方之一。
如果删除source.txt文件,则软链接softsource.txt就会变成红包字体。表示警告,说明这是一个有问题的文件,无法找到它所标识的目标文件source.txt。
4、建立属于你自己的目录链接
[linson@www ~]$ ls -F
operation_tools/
[linson@www ~]$ ln -s operation_tools/ link_tools
[linson@www ~]$ ls -li
123 lrwxrwxrwx. 1 linson linson 16 7月 27 21:50 link_tools -> operation_tools/
drwxrwxr-x. 2 linson linson 6 6月 26 22:30 operation_tools
5、为什么ln不允许硬链接到目录
Linux系统中的硬链接有两个限制:
不能跨越文件系统
不允许普通用户对目录作硬链接
对任何一个目录用ls -l命令都可以看到其链接数至少是2,也说明系统中是存在基于目录的硬链接的,而且命令ln -d(-d选项表示针对目录建立硬链接)也允许root用户尝试对目录作硬链接。这些都说明了系统限制对目录进行硬链接中是一个硬性规定,并不是逻辑上不允许或技术上不可行。那么操作系统为什么要进行这个限制呢?
这是因为,如果引入了对目录的硬连接就有可能在目录中引入循环链接,那么在目录遍历的时候系统就会陷入无限循环当中。也许有人会说,符号连接不也可以引入循环链接吗,那么为什么不限制目录的符号连接呢?
原因就在于,在Linux系统中,每个文件(目录也是文件)都对应着一个inode结构,其中inode数据结构中包含了文件类型(目录、普通文件、符号连接文件等)的信息,也就是说,操作系统在遍历目录时可以判断出其是否是符号连接。既然可以判断出它是否是符号连接,当然就可以采取一些措施来防范进入过大过深的循环层次,于是大部分系统会规定在连续遇到8个符号连接后就停止遍历。但是对于硬链接,由于操作系统中采用的数据结构和算法限制,目前是不能防范这种死循环的。
基于这样的考虑,系统不允许普通用户建立目录硬链接。
6、ln命令的-n选项有点绕
第一步:建立两个文件夹a和b
[linson@www ~]$ mkdir a b
[linson@www ~]$ ls -F
a/
b/
第二步:针对a目录创建软链接c
[linson@www ~]$ ln -s a c
[linson@www ~]$ ls -li
8409184 drwxrwxr-x. 2 linson linson 6 7月 27 22:20 a
12582998 drwxrwxr-x. 2 linson linson 6 7月 27 22:20 b
127 lrwxrwxrwx. 1 linson linson 1 7月 27 22:22 c -> a
第三步:精髓就在这一步
#我们再针对b目录创建软链接c,造成了软链接c的重复定义
[linson@www ~]$ ln -s b c
#软链接c并没有指向b,上一条命令似乎并没有生效
[linson@www ~]$ ls -li
总用量 392
8409184 drwxrwxr-x. 2 linson linson 15 7月 29 20:10 a
12582998 drwxrwxr-x. 2 linson linson 6 7月 27 22:20 b
127 lrwxrwxrwx. 1 linson linson 1 7月 27 22:22 c -> a
#我们进入到软链接c(也就是a目录)中看一看
[linson@www ~]$ cd c/
#竟然发现了一个软链接b指向目录b,而且是死链
[linson@www c]$ ls -li
总用量 0
8409188 lrwxrwxrwx. 1 linson linson 1 7月 29 20:10 b -> b
可以看到,ln会在c软链接目录(也就是a目录)里面创建一个b的软链接文件,且指向b目录,但很明显,这不是你的本意。
如果换成ln -sn b c,那么结果就变了,我们一起来看。
#加上-n选项后,系统发现了软链接重复定义的问题,于是报错了
[linson@www ~]$ ln -sn b c
ln: 无法创建符号链接"c": 文件已存在
#我们使用-f(--force)来强制建立软链接,看看效果
[linson@www ~]$ ln -snf b c
#看,原来指向a的符号链接c,现在已经乘乘地指向b了
[linson@www ~]$ ls -li
总用量 392
8409184 drwxrwxr-x. 2 linson linson 15 7月 29 20:10 a
12582998 drwxrwxr-x. 2 linson linson 6 7月 27 22:20 b
127 lrwxrwxrwx. 1 linson linson 1 7月 29 20:19 c -> b