“ls -l <​​随机文件>”与“wc -c <随机文件>”的字节数

Rok*_*.ma 26 ls wc byte

有没有什么可能的情况

ls -l file.txt
Run Code Online (Sandbox Code Playgroud)

显示的字节数与

wc -c file.txt
Run Code Online (Sandbox Code Playgroud)

在一个脚本中,我发现了这两个值的比较。那可能是什么原因?甚至可能有同一个文件的不同字节数吗?

Ser*_*nyy 13

是的,有这样的案例。

在Linux 系统上使用 GNU符号链接的情况下lsls -l将输出链接的大小,同时wc -c将解析实际文件并读取那里的字节数。下面你可以看到ls -l报告 29 bytes ,而wc实际文件中报告了 172 bytes 。

$ 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
Run Code Online (Sandbox Code Playgroud)

虚拟文件系统的情况下,例如/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 
Run Code Online (Sandbox Code Playgroud)

对于常规文件,大小应该相等。


和 的点ls -l以及wc -c它们的工作方式也不同。wc -c实际上打开文件进行读取(strace wc -c /etc/passwd例如,如果您运行,您可以看到)。ls -lstat()对那些执行调用。这也解释了为什么 in/proc ls -l显示 0 大小 - 您不能统计这些文件,因为它们不是“真实的”或实际存储在硬盘驱动器/ssd 上。wc -c相反,读取该文件的内容,并计算其大小。

最后,ls -l它只是一个交互式列出项目的工具。它很少适合编写脚本。当您确实需要读取数据时,请wc -c改用。

请注意,对于编写脚本和评估文件大小,这ls不是最佳选择。事实上,避免解析ls输出是一种常见的做法。请du -b 用于找出文件的大小。


Muz*_*zer 12

ls -l 将返回文件系统报告的文件大小。

wc -c将尝试读取文件以确定“实际”大小。根据我的观察,它似乎首先尝试寻找到最后,如果这不起作用,它将读出整个文件,并计算它的大小。

这是对这两个工具的作用的简单描述,但它对结果有许多影响:

ls将为某些文件系统提供不正确的输出。例如,虚拟化文件系统/proc会报告许多文件的大小为零,因为这些“文件”实际上并未存储在任何地方;它们是根据软件的需要生成的。

wc将所有没有读取权限的文件无法正常工作,而ls只需要权限列出目录(对比ls -l /etc/shadowwc -c /etc/shadow)。

正如其他答案中提到的,符号链接的行为也不同。因为wc尝试读取它们,它最终会读取符号链接指向的文件,而因为ls只是查询文件系统,它将报告用于存储符号链接本身的大小。

我确定还有其他我还没有想到的差异,但我想我会对这些差异背后的基本原因给出一个清晰而简单的解释。


Cyc*_*ic3 6

对于普通文件,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
Run Code Online (Sandbox Code Playgroud)

这可能是一种确定某些文件是否为特殊文件的方法。

  • `wc -c` 对我来说至少确实调用了 `fstat`,但似乎是出于其他目的。它通过`lseek`找到文件的长度直到结尾。如果这返回错误,则它“读取”整个文件。 (2认同)