İlk N
satırları bir uygulama tarafından aktif olarak eklenmiş olan bir kütükten çıkarmanın bir yolu var mı ?
İlk N
satırları bir uygulama tarafından aktif olarak eklenmiş olan bir kütükten çıkarmanın bir yolu var mı ?
Yanıtlar:
Hayır, Linux gibi işletim sistemleri ve dosya sistemleri, bir dosyanın başındaki verileri kaldırmak için gerekli önlemleri almazlar. Başka bir deyişle, bir dosyanın depolamasının başlangıç noktası sabittir.
Bir dosyanın başlangıcından satırları kaldırmak, genellikle kalan verileri yeni bir dosyaya yazıp eskisini silerek gerçekleştirilir. Bir program eski dosyayı yazmaya açıksa, uygulama dosyayı kapatıncaya kadar bu dosyanın silinmesi ertelenir.
Yorum yapanların da belirttiği gibi, önceki cümlemde verilen nedenlerden dolayı, genellikle günlük dosyasını budama günlüklerini yazan programlarla koordine etmeniz gerekir. Tam olarak bunu nasıl yaptığınız programlara bağlıdır. Bazı programlar, bir sinyal gönderdiğinizde (ör. HUP) günlük dosyalarını kapatır ve yeniden açar ve bu, hizmetin kesilmeden günlük kayıtlarının 'silinen' günlük dosyalarına yazılmasını önlemek için kullanılabilir.
Günlük dosyalarının boyutunu yönetmek için kullanılabilecek birçok yardımcı program vardır, örneğin logrotate
Bazı programların kendi yardımcı programları vardır. Örneğin, Apache web sunucusu bir rotatelog yardımcı programı içerir .
Bence bu görev başarılabilir sed
sed -i '1,10d' myfile
1 çizgileri gidermeye olur st 10 inci çizgi formunda dosyasını.
Bence herkes en azından bu 1 gömleke bir göz atmalı .
Bunun bir uygulama tarafından aktif olarak eklenmiş olan logfile'ler için işe yaramadığını unutmayın (soruda belirtildiği gibi).
sed -i
yeni bir dosya oluşturacak ve yazılmakta olan dosyayı 'silecektir'. Çoğu uygulama silinen günlük dosyasına günlük kayıtları yazmaya ve disk alanını doldurmaya devam edecektir. Yeni, kesilmiş, günlük dosyasına eklenmeyecek. Bu, yalnızca uygulama yeniden başlatıldığında ya da günlük dosyalarını kapatıp yeniden açmak için işaret edildiğinde kesilir. Sed kullanımı ile uygulamanın yeniden başlatılması arasında herhangi bir kayda değer aktivite varsa, bu noktada yeni kayıt dosyasında bir boşluk (eksik kayıt kayıtları) olacaktır.
Bunu yapmanın güvenli bir yolu, uygulamayı durdurmak, günlüğü kesmek için sed komutunu kullanmak ve uygulamayı yeniden başlatmak olabilir. Bu yaklaşım bazı servisler için kabul edilemez (örneğin, yüksek verimli ve yüksek servis sürekliliği gereksinimleri olan bir web sunucusu)
sed -i
oluşturur ve eskisini kaldırır, böylece etkin dosyayı düzenlemezsiniz: ------ Lütfen nasıl çalıştığını kontrol edin . Neden bu yanlış cevabın bu kadar çok olumlu yönü var? $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile
sed -i
Hayır. Günlük dosyası büyümesinin bu genel sorununa bir çözüm günlük döndürmedir. Bu, mevcut bir günlük dosyasının başka bir dosya adına düzenli olarak (gece veya haftalık olarak) taşınmasını ve boş bir günlük dosyasıyla yeni bir başlangıç yapmasını içerir. Bir süre sonra eski günlük dosyaları atılır.
Bkz .: http://www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm
Bu bir cevap , bir çözüm değil. Sorunun hiçbir çözümü yok. Soru sahibi açıkça " Bir uygulama tarafından aktif olarak eklenmiş bir kayıttan". Daha fazla bilgi edinmek için okumaya devam edebilirsiniz ve bu kodun neden en iyi uygulamaları kaydetmeyi takip etmediğine dair varsayımımı temel alarak yaptığım bir öneri için atlayabilirsiniz .
Açık olmak gerekirse: buradaki diğer “cevaplar” yanlış söz veriyor . Hiçbir yeniden adlandırma, uygulamayı yeni dosyayı kullanmaya kandırmaz. Bu yanlış cevaplara yapılan yorumlarda en yararlı bilgiler yer almaktadır.
AKTİF dosyalar basitçe veri koyduğunuz bir tür konteyner değildir. Bir dosya adı BİR inode'a (dosyanın başlangıcı) işaret eder ve her inode'un başka bir inode'a (daha fazla veri varsa) işaretçisi vardır. Bu, sürekli yazılmış bir dosyaya, kendisine eklenen sabit bir inode akışına sahip olduğu ve bir "dosya" hakkında düşündüğünüzün aslında bir inode günlük dizisi olduğu anlamına gelir.
Birini Google Haritalar'da takip ettiğinizi ve bu kişinin dünyanın herhangi bir yerine, herhangi bir zamanda ışınlanabileceğini ve bu noktaları birleştirmeye çalıştığınızı hayal edin.
Linux aracı "truncate", dosya sonunda, sadece inode ağacında yürüyerek verileri atabilir ve (belirlediğiniz yerde / boyutta) yığındaki sonraki tüm işaretleyicileri atar. Dosyanın başında geriye doğru atma - yapmak - inode ağacını gerçek zamanlı olarak kimsenin böyle bir araç yazamayacağı kadar sık sık karmaşık ve riskli bir işlem olurdu - çünkü çoğu zaman başarısız olur ve yol açar. veri kaybı. Wiki Dosyaindeksi kısadır ama bu kavramların bazılarını açıklar.
** Benim tavsiyem: Bu sorunu ters çevirin - Bu uygulama neden bu şekilde davranıyor? Birçok Günlük En İyi uygulaması var, ancak çoğu zaman günlük sisteminizin gerçekte ne olduğuna (syslog vb.) Bağlılar. Çekirdekte bir uygulamanın dosyaya tanıtıcısını "serbest bırakması" beklenir, böylece logrotate (etc) eski verilerin işlenmesini kaldırabilir.
Ne zaman "AKTİF bir günlük dosyasına" duyduğumda hemen bu kişiden bana bu uygulamanın arkasındaki "özel hikayeyi" söylemesini rica ediyorum. Genellikle "geliştirici istifa eder ve kodu değiştiremeyiz. Bu aslında güvenliğin tersidir, kendine özgü riskleri vardır. Ama kaynak koduna dokunmaktan kaçınan bir çözüm istiyorum. Bu durumda, daha spesifik bir soru gereklidir.
Üstün metinle açma Dosyaların eklenmesi halinde bile satırların silinmesi ve kaydedilmesi bir şekilde çalışır, ancak buraya bir komut satırı çözümü için çözüm aramaya geldim, bu yüzden bu çalışmayı ancak işe yaramaz çözümü burada bırakayım !!
Belki kopyala, kes, kopyayı tekrar büyüklük = 0 kesmeye getir ve kopyayı sil?
Kuyruğa kopyalamak için daha iyi, ancak orijinali kısaltın, orijinal üzerine concat kuyruk kopyasını yerleştirin.
Günlükte kuyruk uzunluğunda çizgiler elde edersiniz, bayt uzunluğu sınırından daha iyidir.
Yorumdaki ayrıntıları değiştirme:
İlk önce Python3'te ne istersen bir logger scriptimiz var.
from time import sleep
idx = 0
while 1 == 1:
idx = (idx + 1)
lf = open('tailTrunc.log', 'a')
lf.write("line to file " + str(idx) + '\n')
lf.close()
sleep(0.01)
Öyleyse truncator'umuz var.
#!/usr/bin/env bash
trap "kill 0" EXIT
rm tailTrunc.log
touch tailTrunc.log
python3 logLoop.py &
loggerPID=$!
sleep 1
kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1
trimEnd.log 80 - 89’u gösterir
kütük 90 bittiğini gösterir
Zaten bir isteğin olduğu bir yol var.
Bir çok daha karmaşık konsolidasyon örneği ve yazma akışının nasıl açıldığı veya kapatıldığı, cpu çekirdeği başına ayarlamalar gerektirebilir.