`ls -s`が「0」を出力するのはいつですか


13

もちろん、ファイルが空かどうかをテストする標準的な方法はですが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

サプライヤからは、テストした2つの環境で動作するという主張がありました。言うまでもなく、テストした2つの場所の両方でひどく失敗しました。

それで、私は興味を持ちました。ない場合はls -s、印刷0空のファイルのため?

これはこれまでの私の発見です:

  • Linux上のGFS:4
  • Linux上のext4:0
  • Solaris上のZFS:1
  • Solarisの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

5
テストを見せてください。テストに移植性がないことを証明するハードデータがありますが、さらに必要なものはありますか?
マット

このサーバーでこれまで見た中で最も興味深い質問の1つ。残念なことに、1ポイントしか使えません。
ktf

@ktfいつでも賞金を授与できます。
ジョー

回答:


6

非常に興味深い発見。ls -sファイルが空であるかどうかを確認したことは一度もありませんが、0空のファイルについても報告すると想定していました。

あなたの質問に:マットがすでにコメントしたように、彼らにあなたのテスト結果を見せてください。結果を説明するにはls -s、バイト単位の実際のサイズではなく、ファイルシステム内の割り当てられたブロックの量を報告するようにしてください。明らかに、いくつかのファイルシステム実装は、iノードにNULLポインターを格納する代わりにデータを格納する必要がない場合でもブロックを割り当てます。

この説明はパフォーマンスに関連している可能性があります。空のままになる空のファイルを作成することは、通常の処理の例外です(私が見た最も一般的な使用法は、ファイルの存在がソフトウェアの特定の状態を表すステータスファイルの作成です)。

しかし、通常、作成されたファイルはすぐにデータを取得するため、特定のFSの設計者は、ファイル作成時にすぐにデータブロックを割り当てることに見合うかもしれないので、最初のデータが到着するとこのタスクは既に完了しています。

2番目の理由は、ファイルに過去に消去されたデータが含まれている可能性があることです。最後のデータブロックを解放する代わりに、同じファイルで再利用するためにそのデータブロックを保持する価値があります。

編集:

もう1つの理由が思い浮かびました:値が0より大きいファイルシステムは、RAID + LVM + FS実装であるZFSと、クラスターファイルシステムであるGFSです。両方とも、iノードに保存されていないファイルの整合性を維持するためにメタデータを保存する必要がある場合があります。ls -sこのメタデータに割り当てられたデータブロックのカウントである可能性があります。


4

ほとんどの(すべてではないにしても)他のファイルシステムとは異なり、ZFSはiノードの静的配列を事前に割り当てません。ZFSで空のファイルを作成すると、によって報告された新しいデータブロックが使用されls -sます。

GFSは、他のゼロ以外の結果につながる同期/ロックデータを保存する必要があると思われます。


2

ls -s ファイルに割り当てられているブロック数を報告します。ディレクトリエントリに直接保存されているものは含まれません。

ほとんどの場合、ブロック数は、バイト数をブロックサイズ(バイト単位)で割った値です。

ブロックの数は、スパースファイルの場合より少なくすることができます。たとえば、ほとんどのファイルシステムでは、これにより0ブロックにわたる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がファイルが空かどうかをテストする良い方法だと思うなら、それが機能することを正当化する責任が彼らにあるべきです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.