daha az dosya1 dosya2 | kedi - neden çalışıyor?


21

Kullandığımda less file1 file2"daha az tampon görüntüleyicide" gösterilen her iki dosyayı da alıyorum, ancak less file1 file2 | catstdout'a eklenen her iki dosyanın içeriğini yazdırıyor. "Daha az tampon görüntüleyici" göstermeli mi yoksa bir sonraki komut için stdout'a çıktı üretmeli mi? Bunu yapmak için hangi mekanizma kullanılır?

Yanıtlar:


30

lessmetni stdout'a yazdırır. stdout gider

  • bir terminale (/ dev / tty?) ve varsayılan tampon göstericiyi açar
  • bir boru aracılığıyla başka bir programa borulama yaparken | ( less text | cut -d: -f1)
  • > ( ) ile yönlendirilirken bir dosyayaless text > tmp

Çıktının bir tty'ye gidip gitmediğini kontrol eden "isa tty " adında bir C işlevi vardır (daha az 4.81, main.c, satır 112). Öyleyse, arabellek görüntüleyiciyi kullanır, aksi halde böyle davranır cat.

Bash'ta testi kullanabilirsiniz (bakınız man test).

  • -T FD dosya tanıtıcısı FD bir terminalde açıldı
  • -p DOSYA var ve adlandırılmış bir boru

Örnek:

[[ -t 1 ]] && \
    echo 'STDOUT is attached to TTY'

[[ -p /dev/stdout ]] && \
    echo 'STDOUT is attached to a pipe'

[[ ! -t 1 && ! -p /dev/stdout ]] && \
    echo 'STDOUT is attached to a redirection'

1
tfh STDOUT bir boruya veya yönlendirmeye bağlı değilse, STDOUT'un bir boruya veya yönlendirmeye bağlı olduğunu yazdırmadıkları doğru. Üçünü de bir komut dosyasına koyun. Çağrı bash script.sh, bash script.sh | cat, bash script.sh > file, ve ne olsun çıkış bakın.
HVD

1
stdout"bir dosyaya yazılmış" bir şey değil. Bu senin yapman write() gereken bir şey . lessÇıktısının bir dosya, boru, soket veya blok aygıtı olmasına veya herhangi bir şekilde olmasına bağlı olarak farklı bir işlem yapmak zorunda değildir. Bu sadece bir tty olmadığı için önemlidir, bu yüzden sadece gibi davranır cat. (Bunu bildiğinizi ve açıklamak için yanlış kelimeleri seçtiğinizi farz ediyorum, ama bunu diğer okuyucular için göstereceğimi düşündüm).
Peter Cordes,

Demek istediğim, benim soruma göre daha az kedi gibi davranmak - ya da daha genel: yani bir boru hattında bir sonraki komut gibi davranmak. Anladığım kadarıyla, aynı davranışın farklı bir araçta da uygulandığını kabul edemiyorum.
tfh

@tfh: Hayır, sıradaki olanı less" çözemez " cat. Sadece bir catsonraki ne olursa olsun, stdout bir tty değilse, gibi davranır .
Peter Cordes

@MichaelD .: teşekkürler, cevabımı düzeltti. Bunun lessdevam edeceğini ve terminal boyutlarını almak için bir TCGETS kullanacağını veya bunun bir tty olmadığını keşfediyordum, ama görünüşe göre yanlış tahmin ettim.
Peter Cordes

6

lessstdoutterminal olup olmadığını kontrol eder ve olmadığı gibi davranır cat(stOnayı EOF'ye kadar stdout'a kopyalar).

Bu özellik , bir dosyayı kolayca yeniden yönlendirmeye izin verirken , çıktılarını (örneğin --helpçıktılarını) her zaman gönderen komut dosyaları veya programlar yazmanıza olanak tanır less. Yine de some_command --fullhelp > help.txtstdin'deki boşluk çubuğunun metin veya sayfadan geçmesini beklediğinde berbat olurdu . Bazı komutlar (örneğin man), çıktılarını bir çağrı cihazı aracılığıyla gönderip göndermeyeceğine karar vermek için kendi çıktısını kontrol eder. Eğer man ls > ls.txtkaçarsan, asla$PAGER .

lessBir boru hattına daha fazla aşama eklerken onu tek bir astardan düzenlemeyi unutursanız, kedi benzeri davranışları kullanışlıdır.


lessUçbirim boyutlarını (bir kerede kaç satır gösterileceğini bilmek için ekran boyutu) belirlemeliyiz. ioctl(2)O kullandığı stdoutyine terminal olmayan dava dosyasını kaçınamaz böylece, terminal olmayan üzerinde ENOTTY dönecekti. lessaslında isatty(3)terminal boyutlarını kontrol etmeden önce kullanır , ancak isattysadece tty ioctl kullanarak ve hata eksikliğini kontrol ederek çalışır.

Gibi basit bir çağrı cihazı more(1)(en azından util-linux sürümü) bile bu özelliğe sahiptir, çünkü muhtemelen bu dava için uygulanması en basit mantıklı davranıştır.


Eğer boru şey zaman unutmayın içine less (örneğin grep foo bar.txt | less), açmak için var /dev/ttyklavye girişi için. (Bunu bununla yaptığını görebilirsiniz echo foo | strace less).

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.