有什么可能的情况
ls -l file.txt
显示的字节数与
wc -c file.txt
在一个脚本中,我发现了这两个值的比较。这可能是什么原因?甚至同一文件的字节数是否可能不同?
有什么可能的情况
ls -l file.txt
显示的字节数与
wc -c file.txt
在一个脚本中,我发现了这两个值的比较。这可能是什么原因?甚至同一文件的字节数是否可能不同?
Answers:
是的,有这种情况。
在使用GNU的Linux系统上进行符号链接的情况下ls
,ls -l
会显示出链接的大小,而wc -c
将解析实际文件并读取其中的字节数。在下面您可以看到ls -l
报告29个字节,而wc
实际文件中报告172个字节。
$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 29 1月 17 2016 /etc/resolv.conf -> ../run/resolvconf/resolv.conf
$ wc -c /etc/resolv.conf
172 /etc/resolv.conf
$ wc -c /var/run/resolvconf/resolv.conf
172 /var/run/resolvconf/resolv.conf
$ ls -l /var/run/resolvconf/resolv.conf
-rw-r--r-- 1 root root 172 1月 15 15:49 /var/run/resolvconf/resolv.conf
对于虚拟文件系统,例如/proc
或/sys
,许多文件将显示大小为0 ls -l
。在/dev
文件系统下,我们有各种特殊文件,例如字符设备和块设备- wc -c
挂在这些特殊文件上,并ls -l
显示主要和次要数字,而不是大小。
命名管道将通过来报告为0
字节ls -c
,但wc -c
实际上会读取管道的内容,因此从技术上讲,它将告诉您命名管道中有多少数据:
$ mkfifo named.pipe
$ echo "This is a test" > named.pipe &
[1] 2129
$ ls -l named.pipe
prw-rw-r-- 1 xieerqi xieerqi 0 1月 16 08:40 named.pipe|
$ wc -c named.pipe
15 named.pipe
[1] + Done echo "This is a test" >named.pipe
对于常规文件,大小应相等。
和的要点ls -l
以及wc -c
它们的工作方式也不同。wc -c
实际上会打开文件进行读取(例如,您可以看到运行该文件strace wc -c /etc/passwd
)。ls -l
只stat()
对那些执行呼叫。这也解释了为什么in /proc
ls -l
显示0大小-您不能统计这些文件,因为它们不是“真实的”或实际存储在硬盘驱动器/ ssd中。wc -c
而是读取该文件的内容,然后计算其大小。
最后,ls -l
它只是用于交互式列出项目的工具。它很少适合脚本编写。当您实际需要读取数据时,请wc -c
改用。
请注意,对于脚本编制和评估文件大小,ls
它不是最佳选择。实际上,避免解析ls
输出是一种常见的做法。请du -b
用于查找文件大小。
/sys/
,/proc/
等)可以提供stat
信息。大多数时候,没有令人信服的理由,因此将其省略。示例包括/proc/kcore
报告为可寻址内核内存的大小(通常比可用物理内存大得多)。
ls -l
将返回文件系统报告的文件大小。
wc -c
将尝试读取文件以确定“实际”大小。根据我的观察,它似乎首先尝试搜索到末尾,如果这不起作用,它将读出整个文件,并随着大小进行计数。
这是对这两种工具的作用的简单描述,但是它对结果产生了许多影响:
ls
对于某些文件系统将给出错误的输出。例如,像这样的虚拟文件系统/proc
会报告许多文件的大小为零,因为这些“文件”并未实际存储在任何地方。它们是按软件要求生成的。
wc
将所有没有读取权限的文件无法正常工作,而ls
只需要权限列出目录(对比ls -l /etc/shadow
来wc -c /etc/shadow
)。
如其他答案中所述,符号链接的行为也不同。由于wc
尝试读取它们,最终将读取符号链接指向的文件,而由于ls
仅查询文件系统,它将报告用于存储符号链接本身的大小。
我确定我还没有想到其他差异,但是我想就这些差异背后的基本原因给出一个清晰而简单的解释。
seek()
。在运行strace wc -l
几个大文件后,情况似乎是这样。