もちろん、ファイルが空であるかどうかをテストする標準的な方法はを使用することですが、test -s FILE
顧客の1人が次のテストを含むスクリプトを受け取りました。
RETVAL=`ls -s ./log/cr_trig.log | awk '{print $1}'`
if test $RETVAL -ne 0
then
echo "Badness: Log not empty"
exit 25
fi
ベンダーは、テストした両方の環境で動作すると主張します。言うまでもなく、私がテストした両方の場所で悲惨に失敗しました。
だから気になります。空のファイルはいつls -s
印刷されますか0
?
これまでに私が見つけたものは次のとおりです。
- LinuxのGFS:4
- Linuxのext4:0
- SolarisのZFS:1
- ソラリスのUFS:0
- AIXのjfs:0
- HP-UXのVxFS:0
- HP-UXのHFS:0
- Mac OS XのHFS:0
まだネットワークファイルシステムを調べたことがありません。
質問:他の人にスクリプトが次のようになることをエレガントに説明するにはどうすればよいですか?間違った?
「正しい」バージョンは次のとおりです。
if test ! -s ./log/cr_trig.log
then
echo "Badness: Log not empty"
exit 25
fi
答え1
非常に興味深い発見です。ls -s
ファイルが空であることを確認するために使用したことはありませんが、空の0
ファイルも報告するものとします。
あなたの質問に:もし人主テスト結果を表示するためにコメントを残してください。結果を説明するために、ls -s
実際のサイズ(バイト)ではなくファイルシステムに割り当てられたブロック数を報告する状態。明らかに、一部のファイルシステムの実装では、inodeにNULLポインタを格納する代わりに、データを保存する必要がなくてもブロックを割り当てます。
これの説明はパフォーマンスに関連している可能性があります。空の空のファイルを生成することは、一般的な処理の例外です(私が見た最も一般的な用途は、ファイルの存在がソフトウェアの一部の状態を表す状態ファイルを生成することです)。
ただし、通常、生成されたファイルはいくつかのデータを非常に迅速に取得するため、特定のファイルシステム設計者はファイルが作成されたらすぐにデータブロックを割り当てて、最初のデータが到着したときにタスクがすでに完了するようにすることが価値があると思ったかもしれません。
2番目の理由は、ファイルに過去に削除されたデータが含まれているためです。最後のデータブロックを解放するのではなく、同じファイルで再利用できるようにデータブロックを保持します。
編集する:
もう一つの理由が浮かんでいます。値が0より大きいファイルシステムは次のとおりです。ZFS、RAID + LVM + FSの実装と政府財務大臣、クラスタ化されたファイルシステム。どちらも、inodeに保存されていないファイルの整合性を維持するためにメタデータを保存する必要があるかもしれません。ls -s
このメタデータに割り当てられたデータブロック内の数にすることができます。
答え2
すべてではありませんが、他のほとんどのファイルシステムとは異なり、ZFSは静的inode配列を事前割り当てしません。 ZFSで空のファイルを作成すると、報告されたデータブロックである新しいデータブロックが使用されますls -s
。
GFSは同期/ロックデータを保存する必要があるため、他のゼロ以外の結果が発生しているようです。
答え3
ls -s
ディレクトリエントリに直接保存されているエントリを除き、ファイルに割り当てられたブロック数を報告します。
ほとんどの場合、ブロック数はバイト数をブロックサイズ(バイト単位)で割ったものに等しく、丸められます。
ブロック数は、以下より少ない場合があります。スパースファイル。たとえば、ほとんどのファイルシステムでは、ゼロブロックにまたがる8192バイトのファイルが作成されます。
$ perl -e 'truncate STDOUT, 8192' >a
$ ls -l a
-rw-r--r-- 1 gilles gilles 8192 Nov 1 21:32 a
$ ls -s a
0 a
一方、ファイルシステムがファイルのブロックを事前に割り当てる場合、またはブロックを使用してメタデータを保存する場合は、ブロック数が増える可能性があります。 Zfsが提供する膨大な量の機能と大規模ファイルシステムへの指向を考慮すると、Zfsがファイルサイズとブロック数の間に明確ではない対応があるという事実は驚くべきことではありません。詳細はわかりませんが、ブロック数は異なります。ファイルサイズだけでなく履歴にも依存します(大きなファイルが切り捨てられた場合は、空のファイルに複数のブロックがある可能性があります)。
なぜ間違っているのかを説明すると、ls -s
ファイルサイズではなくファイルシステムに応じた量が計算されます。これはファイルが空であることを確認する非常に間接的な方法で、外部ツール()といくつかの解析が必要です。代わりに、解析を必要とせずに要求された操作を正確に実行するツールをls
使用する必要があります。test -s
これがファイルが空であるかどうかをテストするための良い方法であると思われる場合は、ls -s
それが機能していることを証明する責任はそれらにあるべきです。