Sebuah skrip yang saya tulis melakukan sesuatu dan, pada akhirnya, menambahkan beberapa baris ke file log-nya sendiri. Saya ingin menyimpan hanya n baris terakhir (katakanlah, 1000 baris) dari file log. Ini dapat dilakukan di akhir skrip dengan cara ini:
tail -n 1000 myscript.log > myscript.log.tmp
mv -f myscript.log.tmp myscript.log
tetapi adakah solusi yang lebih bersih dan elegan? Mungkin dicapai melalui satu perintah?
text-processing
tail
logs
dr01
sumber
sumber
logrotate
adalah solusi eleganJawaban:
Mungkin seperti ini, tetapi seperti yang orang lain katakan, opsi teraman adalah pembuatan file baru dan kemudian memindahkan file itu untuk menimpa yang asli.
Metode di bawah ini memuat baris ke BASH, jadi tergantung pada jumlah baris dari
tail
, itu akan mempengaruhi penggunaan memori shell lokal untuk menyimpan konten dari baris log.Di bawah ini juga menghapus baris kosong jika ada di akhir file log (karena perilaku BASH mengevaluasi
"$(tail -1000 test.log)"
) sehingga tidak memberikan pemotongan 100% akurat di semua skenario, tetapi tergantung pada situasi Anda, mungkin cukup.sumber
Utilitas
sponge
ini dirancang hanya untuk kasus ini. Jika Anda menginstalnya, maka dua baris Anda dapat ditulis:Biasanya, membaca dari file pada saat yang sama dengan saat Anda menulis tidak dapat diandalkan.
sponge
menyelesaikan ini dengan tidak menulismyscript.log
sampai setelahtail
selesai membacanya dan menghentikan pipa.Install
Untuk menginstal
sponge
pada sistem seperti Debian:Untuk menginstal
sponge
pada sistem RHEL / CentOS, tambahkan repo EPEL dan kemudian lakukan:Dokumentasi
Dari
man sponge
:sumber
sponge
. Sangat berguna untuk semua orang yang belajar dengan cara yang sulit yang tidak dapat Anda lakukansort importantfile.txt > importantfile.txt
:)pasti "tail + mv" jauh lebih baik! Tetapi untuk gnu sed kita bisa mencoba
sumber
Sebagai catatan, dengan
ed
Anda bisa melakukan sesuatu sepertiIni terbuka
infile
danr
keluar di outputtail -n 1000 infile
(yaitu memasukkan output sebelum baris 1) dan kemudian menghapus dari apa yang awalnya baris 1 ke akhir file. Ganti,p
denganw
untuk mengedit file di tempat.Perlu diingat bahwa
ed
solusi tidak cocok untuk file besar.sumber
Apa yang dapat Anda lakukan dalam skrip Anda adalah menerapkan logika rotasi log. Lakukan semua penebangan melalui fungsi:
Fungsi ini, pertama, melakukan sesuatu seperti:
kemudian, ia memeriksa ukuran file atau entah bagaimana memutuskan bahwa file tersebut memerlukan rotasi. Pada titik itu, file
logfile.1
, jika ada, dihapus, file itulogfile.0
, jika ada, diubah namanya menjadilogfile.1
danlogfile
diubah namanya menjadilogfile.0
.Memutuskan apakah akan memutar dapat didasarkan pada penghitung yang disimpan dalam skrip itu sendiri. Ketika mencapai 1000, itu diatur ulang ke nol.
Jika selalu memangkas dengan ketat menjadi 1000 baris adalah persyaratan, skrip dapat menghitung jumlah baris dalam file log saat dimulai, dan menginisialisasi penghitung yang sesuai (atau jika hitungan sudah memenuhi atau melebihi 1000, lakukan rotasi segera).
Atau Anda bisa memperoleh ukuran, seperti dengan
wc -c logfile
dan melakukan rotasi berdasarkan melebihi ukuran tertentu. Dengan cara ini file tidak pernah dipindai untuk menentukan kondisinya.sumber
Saya memang menggunakan, alih-alih
mv
,cp
perintah untuk mencapainya sehingga Anda dapat memiliki beberapa file log di tempat di mana Perangkat Lunak berjalan. Mungkin di direktori home User yang berbeda atau di dir aplikasi dan memiliki semua log di satu tempat sebagai hardlink. Jika Anda menggunakanmv
perintah, Anda kehilangan tautan yang sulit. Jika Anda menggunakancp
perintah, Anda akan menyimpan tautan keras ini.kode saya adalah sesuatu seperti:
Jadi jika file berada pada Filesystem yang sama Anda dapat memberikan juga beberapa hak berbeda kepada pengguna dan
${LOGFILE_DIR}
Anda memodifikasi panjang seperti yang saya lakukan.Jika itu
mv
perintah Anda kehilangan hardlink antara file dan file kedua Anda tidak lebih terhubung dengan yang pertama - mungkin ditempatkan beberapa tempat lain.Jika di tempat lain Anda tidak mengizinkan seseorang untuk menghapus file log Anda tetap bersama dan dikontrol dengan baik melalui skrip Anda sendiri.
logrotate
mungkin lebih baik. Tapi saya senang dengan solusi ini.Jangan diganggu oleh "" tetapi dalam kasus saya ada beberapa file dengan spasi dan huruf khusus lainnya di dalam dan "" Jika saya tidak melakukan "" sekitar atau {} seluruh banyak tidak berfungsi dengan baik.
Sebagai contoh ada Dir di mana file yang lebih lama otomatis dizip menjadi
OLDFILE.zip
dan segala sesuatu yang di-zip juga tercantum dalam File.zip_log
sehingga.zip_log
ada di Dir ini juga tetapi diLOGFILE_DIR
saya punya dengan:file yang sama dengan itu adalah tautan keras.
sumber