İsatty () bilgileri terminalden nasıl alır?


4

Eğer yazarsam şunu fark ettim:

ls --color=auto

veya

ls --color=auto | cat
ls --color=auto > >(cat)

Aynı çıktıyı göremiyorum. Bu nedenle, bir programın STDOUT'un bir şeye bağlanmış olup olmadığını bilme kabiliyetine sahip olduğunu varsayıyorum. Soru, nasıl biliyor?

ENV değişkenlerini kontrol ettim envve env | cataynı şeyi aldım. Cevap başka bir yerde. Nerede olduğunu çözemiyorum.

Bu sorudanisatty() , bu fonksiyonu sağlayanı kullanabileceğimi öğrendim ? kabuğun veya çekirdeğin bir parçası mı? Daha da ileri giderek, bu fonksiyonun POSIX standardının bir parçası olduğunu görüyorum.

Artık, aralarında birkaç mekanizma ile iletişim kurabilen iki sürecin olduğunu biliyorum:

  • STDIN / STDOUT / STDERR
  • Koddan çık
  • Ortam Değişkenleri
  • Sistem çağrıları

Bash ve ls her ikisi de programdır. Böylece bilgi alışverişinde sadece listelenen mekanizmaları kullanabilirler.

Bunun arkasındaki asıl soru isatty(), bilgileri bash'tan nasıl alıyor?


@Steven - Bu tamamen farklı bir problem.
AFH

@AFH gerçekten değil. Steven'ın verdiği cevapla, bir programın POSIX işlevini kullanacağını öğrendim isatty(). Sorumu şu şekilde değiştirmem gerekecek: isatty()Bir işlev kabuğa mı yoksa çekirdeğe mi bağlı?
nowox

1
@Steven Üzgünüm kafam karıştı ve bir XY problemi sordum ...
nowox

Yanıtlar:


5

Bu --colorseçenek GNU lsprogramının bir özelliğidir . GNU , işlemin standart çıktısının bir TTY olup olmadığını test etmek lsiçin isatty()işlevi kullanır . İlgili kaynak kodunun bir kısmı burada görülebilir :

    case COLOR_OPTION:
      {
        int i;
        if (optarg)
          i = XARGMATCH ("--color", optarg, color_args, color_types);
        else
          /* Using --color with no argument is equivalent to using
             --color=always.  */
          i = color_always;

        print_with_color = (i == color_always
                            || (i == color_if_tty
                                && isatty (STDOUT_FILENO)));

Bunun arkasındaki asıl soru isatty () bilgiyi bash'tan nasıl alıyor?

isatty()dosya tanımlayıcısının bir TTY'yi (terminal cihazı) temsil edip etmediğini görmek için kendisine verilen dosya tanımlayıcısını inceler. İsatty () işlevinin tam yolu bir sistemden diğerine değişebilir. İşte ilgileniyorsanız, Apple OSX'ten bir Darwin uygulaması :

#include <termios.h>
#include <unistd.h>

int
isatty(fd)
    int fd;
{
    struct termios t;

    return(tcgetattr(fd, &t) != -1);
}

Çalıştırdığınızda ls --color=auto, kabuğunuz (bash) kabuğun kendi standart girişini, çıktısını ve hatasını "ls" işlemi için stdin / out / err olarak kullanarak "ls" programını başlatır. Eğer etkileşimli çalışıyorsanız, kabuğunuzun stdout'u muhtemelen bir terminaldir, o zaman ls'nin standart çıkışı muhtemelen bir terminal olacaktır. Ls, standart çıktısının bir terminal olup olmadığını test etmek için isatty () işlevini çağırdığında, muhtemelen başarılı olur.

Gibi bir şey çalıştırdığınızda ls --color=auto | cat, kabuğunuz üç şey yapar:

  1. Bir boru oluştur.
  2. catBoru olacak şekilde standart girişi ayarlanmış olarak başlatın .
  3. lsBoru olarak ayarlanmış standart çıkışı ile başlatın .

Bir boru bir terminal değildir. Ne zaman lstestler standart çıktı bir tty olup olmadığını test başarısız olur.

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.