Skrip shell Unix untuk memotong file besar

87

Saya mencoba menulis skrip Unix yang akan memotong / mengosongkan file yang terus-menerus ditulis / dibuka oleh aplikasi ketika mencapai, katakanlah ruang 3GB. Saya tahu bahwa perintah di bawah ini akan melakukannya:

cp /dev/null [filename]

Tetapi saya akan menjalankan ini di lingkungan produksi secara otomatis sebagai tugas cron - cukup posting di sini untuk melihat apakah kalian menghadapi masalah saat melakukan sesuatu yang serupa dengan ini.

peedee
sumber
Ini adalah prod. log tidak memiliki nilai? Saya beruntung menyimpan log produksi saya selama satu tahun + (dalam bzip2 -9 fmt) dan memiliki beberapa utilitas kecil yang membuatnya mudah untuk mengekstrak runtime pekerjaan, catatan diproses, dan ketika dimuat ke spreadsheet mudah dihitung dan rasio pemuatan grafik dan banyak hal lainnya. Kami menemukan masalah hdwr karena penurunan rasio beban. Ya, ada alat pemantauan yang bagus di luar sana, jadi semuanya tergantung pada situasi Anda. SEBAGAI PILIHAN TERPISAH, pernahkah Anda melihatnya logrotate, ini mungkin memberi Anda beberapa nilai (tetapi mengganggu pengaturannya (hanya menebak-nebak)!).
shellter
5
Perhatikan bahwa jika file log dibuka dengan bendera O_APPEND, maka pemotongan efektif. Jika tidak dibuka dengan flag O_APPEND, maka program akan melanjutkan penulisan dengan offset 3 GiB (pertama kali); sistem akan memperlakukan 3 GiB pertama sebagai semua-byte-nol (yang terkompresi dengan baik), tetapi file akan terus bertambah. Itu semua tergantung pada program yang menulis log.
Jonathan Leffler

Jawaban:

116

Hanya untuk menambahkan jawaban lain,

: > filename

: adalah no-op di bash (sesuai dengan POSIX), jadi ini pada dasarnya hanya membuka file untuk ditulis (yang tentu saja memotong file) dan kemudian segera menutupnya.

EDIT: seperti yang dikomentari shellter, Anda sebenarnya tidak memerlukan perintah untuk mengikuti pengalihan:

$ echo foo > foo.txt
$ cat foo.txt
foo
$ > foo.txt
$ cat foo.txt
$

Pengalihan sederhana dengan sendirinya akan menghapus file.

chepner
sumber
25
atau hanya > filename(seperti yang saya yakin Anda tahu). Semoga beruntung untuk semuanya.
shellter
5
@shelter "$> file" bukan POSIX dan bukan portabel. Anda harus menggunakan perintah ":" no-op sebelum mengalihkan, seperti yang disarankan pada awalnya.
Aaron Toponce
2
+ plus untuk wajah tersenyum
Chris Suszyński
2
Seperti yang dikatakan @AaronToponce, "$> file" memang tidak portabel; pada pengaturan Zsh saya itu membuat shell hang (seharusnya menunggu input). "$:> file" berfungsi dengan baik di Zsh.
Linus Arver
1
@TechEnthusiast Itu tergantung pada harapan Anda. Pemotongan itu sendiri adalah atom, tetapi Anda tidak benar-benar tahu kapan itu akan terjadi relatif terhadap penulisan tertentu. Anda bisa, misalnya, berakhir dengan garis parsial di awal file.
chepner
66

Saya telah menggunakan perintah berikut di debian

truncate -s 0 filename
Ricardo Marimon
sumber
@SteveClay: sudo sh -c ': > filename'juga akan memotongfilename
Perleone
2
@SteveClay The Ops Saran juga bekerja sempurna dengan sudo: sudo cp /dev/null filename. Juga cpportabel sementara truncatehanya untuk Linux modern.
Tino
11

Sepertinya itu masuk akal bagi saya. Unix, tentu saja, akan membiarkan Anda melakukan ini dengan 50 cara berbeda. Sebagai contoh,

echo -n "" >filename
cat /dev/null >filename
Don Branson
sumber
2

trunc filename

bekerja pada AIX flavor dari UNIX

San
sumber