可能なシナリオがありますか?
ls -l file.txt
表示されるバイト数は次のとおりです。
wc -c file.txt
スクリプトはこれら2つの値の比較を見つけました。その理由は何ですか?同じファイルのバイト数が異なる可能性がありますか?
答え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
そこにある多くのファイルのサイズがゼロであるように見えますls -l
。ファイルシステムには、/dev
キャラクターデバイス、ブロックデバイスなど、さまざまな特殊ファイルがあります。wc -c
このファイルをぶら下げてls -l
表示します。プライマリ番号とセカンダリ番号サイズではなく
名前付きパイプ0
bytesとして報告されますが、パイプの内容は実際に読み取られるため、技術的に名前付きパイプにどれだけのデータがあるかを知らせます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
たとえば、実行するとわかるように)。その項目に対してのみ呼び出しを行います。これはまた、サイズがゼロで表される理由を説明します。これらのファイルは「実際」ではないか、実際にはハードドライブ/ 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
これはファイルが特別であるかどうかを判断する方法です。