Linux中file命令及ln命令的使用

一、探寻文件信息的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

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180420A157JW00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券