可能な状況はありますか
ls -l file.txt
と同じバイト数ではありません
wc -c file.txt
1つのスクリプトで、これら2つの値の比較を見つけました。その理由は何でしょうか?同じファイルの異なるバイト数を持つことさえ可能ですか?
可能な状況はありますか
ls -l file.txt
と同じバイト数ではありません
wc -c file.txt
1つのスクリプトで、これら2つの値の比較を見つけました。その理由は何でしょうか?同じファイルの異なるバイト数を持つことさえ可能ですか?
回答:
はい、そのような場合があります。
以下の場合はシンボリックリンク GNUとLinuxシステム上でls
、ls -l
一方で、リンクの大きさを出しますwc -c
実際のファイルを解決し、そこバイト数を読み込みます。以下では、実際のファイルで172バイトls -l
をwc
報告するのに対し、29バイトを報告することがわかります。
$ 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()
呼び出しを実行します。これはまた、/proc
ls -l
サイズが0である理由を説明します。これらのファイルは「実際の」ものではないか、実際にハードドライブ/ ssdに保存されていないため、統計できません。wc -c
代わりに、そのファイルの内容を読み取り、サイズを計算します。
最後に、ls -l
インタラクティブにアイテムをリストするためのツールのみです。スクリプトに適していることはめったにありません。実際にデータを読み取る必要がある場合は、wc -c
代わりに使用します。
スクリプトの作成とファイルのサイズの評価にls
は最適な候補ではないことに注意してください。実際、出力の解析ls
を回避することは一般的な方法の1つです。du -b
ファイルのサイズを調べるために使用してください。
/sys/
、/proc/
など)も提供stat
への実装を選択した場合、情報を。ほとんどの場合、説得力のある理由はないため、省略されています。例には/proc/kcore
、アドレス可能なカーネルメモリのサイズとして報告されるものが含まれます(通常、使用可能な物理メモリよりもはるかに大きい)。
ls -l
ファイルシステムによって報告されたファイルのサイズを返します。
wc -c
ファイルを読み取って「実際の」サイズを決定しようとします。私の観察から、最初に最後までシークしようとしているように見えます。これが機能しない場合、ファイル全体を読み取り、サイズをカウントします。
これは、2つのツールの機能に関する簡単な説明ですが、結果に多くの影響を与えます。
ls
特定のファイルシステムに対して誤った出力を提供します。たとえば、/proc
これらの「ファイル」は物理的にどこにも保存されていないため、多くのファイルのような仮想化ファイルシステムはゼロのサイズを報告します。それらはソフトウェアの必要に応じて生成されます。
wc
一方、読み取り権限のないファイルのすべてのでは機能しませんls
(比較ディレクトリ一覧表示するだけの権限を必要とls -l /etc/shadow
するがwc -c /etc/shadow
)。
他の回答で述べたように、シンボリックリンクの動作も異なります。wc
それらを読み取ろうとするため、シンボリックリンクが指すファイルを読み取ることになりますがls
、ファイルシステムを照会するだけなので、シンボリックリンク自体を保存するために使用されるサイズを報告します。
私はまだ考えていない他の違いがあると確信していますが、これらの違いの背後にある基本的な理由について明確で簡単な説明をすると思いました。
seek()
。これstrace wc -l
は、いくつかの大きなファイルで実行した後のケースのようです。
通常のファイルの場合、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
これはおそらく、何かが特別なファイルであるかどうかを調べる何らかの方法です。
wc -c
私にとっては少なくともを呼び出しますfstat
が、一見他の目的のために。lseek
最後までingすることにより、ファイルの長さを見つけます。これがエラーを返す場合、read
ファイル全体です。