是否有任何可能的情况
ls -l file.txt
显示的字节数与
wc -c file.txt
在一个脚本中,我发现了这两个值的比较。这可能是什么原因?同一文件是否可以有不同的字节数?
答案1
是的,有这样的例子。
的情况下符号链接在使用 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
如果您运行,您可以看到)。只对那些执行调用。这也解释了为什么显示 0 大小 - 您无法统计这些文件,因为它们不是“真实的”或实际存储在硬盘驱动器/SSD 上。相反,读取strace wc -c /etc/passwd
ls -l
stat()
/proc
ls -l
wc -c
内容该文件的大小,并计算其大小。
最后,ls -l
只是一个交互式列出项目的工具。它很少适合编写脚本。当您确实需要读取数据时,请wc -c
改为使用。
请注意,对于编写脚本和评估文件大小来说,ls
这不是最佳选择。事实上,这是一种常见的做法避免解析ls
输出。请用于du -b
查找文件的大小。
答案2
ls -l
将返回文件系统报告的文件的大小。
wc -c
将尝试读取文件以确定“实际”大小。根据我的观察,它似乎首先尝试查找到末尾,如果这不起作用,它将读出整个文件,并计算大小。
这是对这两个工具的作用的简单描述,但它对结果产生了许多影响:
ls
对于某些文件系统将会给出不正确的输出。例如,虚拟化文件系统/proc
会报告许多文件的大小为零,因为这些“文件”实际上没有存储在任何地方;它们是根据软件的要求生成的。
wc
对于没有读取权限的文件根本不起作用,而ls
只需要列出目录的权限(ls -l /etc/shadow
与相比wc -c /etc/shadow
)。
正如其他答案中提到的,符号链接的行为也不同。因为wc
尝试读取它们,所以它最终会读取符号链接指向的文件,而因为ls
只是查询文件系统,它将报告用于存储符号链接本身的大小。
我确信还有其他我还没有想到的差异,但我想我应该对这些差异背后的基本原因给出一个清晰而简单的解释。
答案3
对于普通文件,ls 和 wc 调用 stat。但是,对于 /proc 或 /sys 的文件,ls 返回 0,但 wc 返回不同的数字:
$ ls -l /proc/modules
-r--r--r-- 1 root root 0 Jan 16 14:56 modules
^ this one
$ wc -c /proc/modules
7621 modules
这可能是查明某个文件是否为特殊文件的某种方法。