Neden “tail -f… | tail ”herhangi bir çıktı üretemedi mi?


36

Aşağıdaki komut neden çıktı vermiyor?

$ tail -f /etc/passwd | tail

Tamponlama hakkında okuduktan sonra , boşuna aşağıdakileri denedim:

$ tail -f /etc/passwd | stdbuf -oL tail

Aşağıdakilerin çıktı ürettiğini unutmayın:

$ tail /etc/passwd | tail

Yani bu mu:

$ tail -f /etc/passwd | head

Kuyruk sürümü 8.21 kullanıyorum (GNU coreutils).


17
Π'nin son 10 hanesi nedir?
Keith Thompson,

Yanıtlar:


15

UNIX'te her şeyi gördüğümü sanıyordum. Bu soru beni düzgünlüğümden mahrum etti. Ne güzel bir soru!

tailson X satırını gösterir. tail -faynısını yapar, ancak esasen sonsuz bir döngüde gerçekleşir: başlangıçta, dosyanın son X satırını gösterip ardından bazı işletim sistemi sihrini kullanarak (inotify gibi) izleyin ve yeni satırları gösterin.

İşini tailyapabilmek için dosyanın sonunu bulabilmeniz gerekir. Eğer taildosyanın sonuna bulamıyorum "son" tanımsız, bunun nedeni, son X hatları gösteremez. Peki tailbu durumda ne yapar ? Dosyanın sonunu bulana kadar bekler.

Bunu düşün:

$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f

Bu asla ilerleme kaydetmedi gibi görünmektedir, çünkü kesin bir dosya sonu yoktur chatter.

tailBir dosya sistemi borusundan son satırları vermek isterseniz aynı davranışı elde edersiniz. Düşünmek:

$ mkfifo test.pipe
$ tail test.pipe

stdbufalgılanan problemi aşmak asil bir girişimdi. Olsa da, asıl önemli olan G / Ç arabelleklemesinin kök nedeni olmaması: kesin bir dosya sonu eksikliği. Tail.c kaynak kodunu kontrol ederseniz , file_linesişlev yorumunun okuduğunu görürsünüz :

END_POS, EOF'nin dosya ofsetidir (bir tanesi son baytın ofsetinden daha büyük).

ve bu sihir. Herhangi bir konfigürasyonda kuyruk çalışması için dosyanın sonuna ihtiyacınız var. headBu kısıtlamaya sahip değil, sadece bir dosya başlangıcına ihtiyaç duyuyor (ki bu olmayabilir head test.pipe). Akışa yönelik araçlar , dosyanın başlangıcını veya sonunu beğenmeyen sedve awkgereksinim duyan araçlar : arabelleklerde çalışırlar.


37

tail -fKuyruğu aslında günümüzde bilinmeyen bir şeydir, o halde bir sonraki nasıl bilmeli tail? Öte yandan tail -f, baş zaten bilinen ve bunun için işlenebilecek bir şey.

Ya da daha basit hale getirmek için: tailDosyanın sonuna görecelidir, ancak çıkış akımı tail -fEOF içermez (en azından sonlandırılmasından önce değil).

İlk bulursanız tail'ın pid ve onu öldürmek için önce gereken sonra ikinci çıkış görebilirsiniz.


21

Teknik cevap

Girdi olarak bir akışla çalışırken, akışı okur gibi dolduğu bir satır arabelleği tailtutar n, ancak akıştan sonuna kadar bu satırları çıkaramaz, yani EOFgirişten okumaya çalışırken özel bir kod alır. Akış. İstisna tail -fçıkış yapmaz, bu nedenle akışını asla kapatmaz, bu da örneğin akışın son 10 satırını geri döndürmeyi imkansız kılar.


3

İşlevi tailgiriş veya dosyanın son bölümünü - "kuyruk" - göstermektir. (Seçenek -fdaha sonra ne yaptığı ile ilgilidir, bu nedenle burada ilgili değildir.)

Bir dosya düşünelim:

Bir dosyanın son kısmı nedir ?
Diyelim ki bir dosyanın son n satırı .

iGiriş dosyasının satırını okuduğumuzda , basılması veya basılmaması gerektiğine nasıl karar verilir?
Son bölümde olup olmadığını bilmiyoruz - çünkü son satırın hangisi olacağını bilmiyoruz. Bu yüzden olamaz şimdi print.

Biz gerek çizgi tutmak berraklaşıncaya kadar son bir 's parçası olduğunu nbildiğimiz çünkü, çizgiler veya artık bunun bir parçası olabilir nilave çizgiler

Şimdi dosyanın sonuna gelirsek , nsakladığımız son nsatırların aslında dosyanın son satırları olduğunu biliyoruz .

Şimdi, durumunda

tail -f /etc/passwd | tail

İlk önce taildosyayı okur, sonra da ondan daha fazla veri almak için bekler . Bu yüzden, okuduğu dosyanın sonuna geldiğinde, ikinci kuyruğa dosyanın bir ucunu işaret etmeyecektir . Bu olmadan, ikincisi tail hiçbir zaman dosyanın sonundan haberdar edilmez , bu nedenle yazdırması gereken son satırların hangisi olduğunu asla bulamaz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.