Tentu saja, cara standar pengujian jika file kosong adalah dengan test -s FILE
, tetapi salah satu klien kami telah menerima skrip yang berisi tes seperti ini:
RETVAL=`ls -s ./log/cr_trig.log | awk '{print $1}'`
if test $RETVAL -ne 0
then
echo "Badness: Log not empty"
exit 25
fi
dengan klaim dari pemasok bahwa ia bekerja di dua lingkungan yang telah mereka uji. Tidak perlu dikatakan, itu gagal parah di kedua tempat saya mengujinya.
Jadi, saya jadi penasaran. Kapan ls -s
mencetak 0
untuk file kosong?
Ini temuan saya sejauh ini:
- GFS di Linux: 4
- ext4 di Linux: 0
- ZFS pada Solaris: 1
- UFS di Solaris: 0
- jfs di AIX: 0
- VxFS di HP-UX: 0
- HFS pada HP-UX: 0
- HFS pada Mac OS X: 0
Saya belum memeriksa sistem file jaringan.
Pertanyaan: Bagaimana saya bisa menjelaskan dengan elegan kepada yang lain bahwa skrip mereka salah ?
Menurut pendapat saya, versi "yang benar" adalah:
if test ! -s ./log/cr_trig.log
then
echo "Badness: Log not empty"
exit 25
fi
filesystems
shell-script
ls
compatibility
MattBianco
sumber
sumber
Jawaban:
Temuan yang sangat menarik. Meskipun saya tidak pernah digunakan
ls -s
untuk memeriksa apakah suatu file kosong atau tidak, saya akan berasumsi, bahwa itu melaporkan0
untuk file kosong juga.Untuk pertanyaan Anda: Seperti yang sudah dikomentari Mat , tunjukkan pada mereka hasil tes Anda. Untuk menjelaskan hasilnya kepada mereka, nyatakan bahwa
ls -s
melaporkan jumlah blok yang dialokasikan dalam sistem file, bukan ukuran sebenarnya dalam byte. Jelas beberapa implementasi sistem file mengalokasikan blok bahkan jika mereka tidak harus menyimpan data apa pun alih-alih hanya menyimpan pointer NULL di inode.Penjelasan untuk ini mungkin terkait kinerja. Untuk membuat file kosong yang akan tetap kosong adalah pengecualian untuk pemrosesan normal (penggunaan paling umum yang pernah saya lihat adalah pembuatan file status di mana keberadaan file mewakili keadaan tertentu dari perangkat lunak).
Tetapi biasanya file yang dibuat akan mendapatkan beberapa data segera, sehingga para perancang FS tertentu mungkin berasumsi bahwa itu akan langsung dibayarkan untuk segera mengalokasikan blok data pada saat pembuatan file, jadi ketika data pertama tiba, tugas ini sudah dilakukan.
Alasan kedua bisa jadi file telah berisi data di masa lalu yang telah dihapus. Alih-alih membebaskan blok data terakhir mungkin layak untuk menjaga blok data tersebut untuk digunakan kembali oleh file yang sama.
EDIT:
Satu lagi alasan muncul di pikiran: Filesystem di mana Anda telah menemukan nilai> 0 adalah ZFS , implementasi RAID + LVM + FS dan GFS , sebuah filesystem cluster. Keduanya mungkin harus menyimpan metadata untuk mempertahankan integritas file yang tidak disimpan dalam inode. Bisa jadi itu
ls -s
diperhitungkan dalam blok data yang dialokasikan untuk metadata ini.sumber
Tidak seperti kebanyakan (jika tidak semua) sistem file lainnya, ZFS tidak mengalokasikan array inode statis. Membuat file kosong di ZFS kemudian akan menggunakan blok data baru yang dilaporkan oleh
ls -s
.Saya menduga GFS harus menyimpan sinkronisasi / mengunci data yang mengarah ke hasil bukan nol lainnya.
sumber
ls -s
melaporkan jumlah blok yang dialokasikan untuk file, tidak termasuk apa pun yang disimpan langsung di entri direktori.Dalam kebanyakan kasus, jumlah blok adalah jumlah byte yang dibagi dengan ukuran blok dalam byte, dibulatkan ke atas.
Jumlah blok bisa kurang dari itu untuk file yang jarang . Misalnya, pada sebagian besar sistem file, ini akan membuat file 8192-byte yang mencakup 0 blok:
Sebaliknya, jumlah blok bisa lebih banyak jika sistem file preallocates blok untuk file atau menggunakan blok untuk menyimpan metadata. Saya tidak terkejut bahwa Zfs memiliki korespondensi yang tidak jelas antara ukuran file dan jumlah blok, mengingat sejumlah besar fitur yang ditawarkannya dan orientasinya terhadap sistem file besar; Saya tidak tahu detailnya, tetapi jumlah blok tidak hanya tergantung pada ukuran file tetapi juga pada sejarahnya (Anda dapat memiliki lebih dari satu blok dalam file kosong jika itu adalah hasil dari pemotongan file yang lebih besar).
Untuk menjelaskan mengapa
ls -s
itu salah: ia tidak menghitung ukuran file, tetapi kuantitas yang bergantung pada filesystem. Ini adalah cara yang sangat tidak langsung untuk menentukan apakah file kosong di tempat pertama, memerlukan alat eksternal (ls
) dan beberapa penguraian; sebagai gantinya, mereka harus menggunakantest -s
, yang tidak memerlukan penguraian, dan melakukan persis apa yang diminta. Jika mereka berpikir ituls -s
adalah cara yang baik untuk menguji apakah suatu file kosong, tanggung jawab harus ada pada mereka untuk membenarkan bahwa itu berfungsi.sumber