Pergunta

Estou tendo um olhar para o código para o utilitário 'menos', especificamente como ele recebe entrada de teclado. Curiosamente, na linha 80 da ttyin.c, ele define o descritor de arquivo para ler:

     /*
      * Try /dev/tty.
      * If that doesn't work, use file descriptor 2,
      * which in Unix is usually attached to the screen,
      * but also usually lets you read from the keyboard.
      */
  #if OS2
      /* The __open() system call translates "/dev/tty" to "con". */
      tty = __open("/dev/tty", OPEN_READ);
  #else
      tty = open("/dev/tty", OPEN_READ);
  #endif
      if (tty < 0)
          tty = 2;

Não é descritor de arquivo 2 stderr? Se assim for, WTH ?! Eu pensei que a entrada do teclado foi enviada através de stdin.

Curiosamente, mesmo se você fizer ls -l * | less, após o carregamento acabamentos de arquivo, você ainda pode usar o teclado para rolar para cima e para baixo, mas se você fizer ls -l * | vi, então vi vai gritar com você, porque ele não lê de stdin. Qual é a grande idéia? Como eu fui acabar nessa estranha nova terra onde stderr é tanto uma maneira de reportar erros para o ecrã e ler a partir do teclado? Eu não acho que estou mais no Kansas ...

Foi útil?

Solução

$ ls -l /dev/fd/
lrwx------ 1 me me 64 2009-09-17 16:52 0 -> /dev/pts/4
lrwx------ 1 me me 64 2009-09-17 16:52 1 -> /dev/pts/4
lrwx------ 1 me me 64 2009-09-17 16:52 2 -> /dev/pts/4

Quando logado em um terminal interative, todos os três descritores de arquivo padrão apontar para a mesma coisa:. O TTY (ou pseudo-TTY)

$ ls -fl /dev/std{in,out,err}
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdin -> fd/0
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdout -> fd/1
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stderr -> fd/2

Por convenção, lemos 0 e gravação para 1 e 2. No entanto, nada nos impede de fazer o contrário.

Quando o shell é executado ls -l * | less, cria-se um tubo de ls descritor de arquivo de 1 para less descritor de arquivo de 0. Obviamente, less já não pode ler a entrada do teclado do utilizador a partir 0 descritor de arquivo -. Ele tenta obter o TTY de volta no entanto, pode

Se less não foi separado do terminal, open("/dev/tty") vai dar-lhe o TTY.

No entanto, no caso de falhar ... o que você pode fazer? less faz uma última tentativa de obter o TTY, assumindo que 2 descritor de arquivo é anexado à mesma coisa que 0 descritor de arquivo será anexado a, se não fosse redirecionada.

Este não failproof:

$ ls -l * | setsid less 2>/dev/null

Aqui, less é dada sua própria sessão (por isso não é mais uma parte do grupo processo ativo do terminal, causando open("/dev/tty") a falhar), e sua 2 descritor de arquivo foi alterado - agora saídas less imediatamente, porque é outputting a um TTY ainda não consegue obter qualquer entrada do usuário.

Outras dicas

Bem ... em primeiro lugar, você parece faltar a chamada open() que abre '/ dev / tty'. Ele utiliza apenas descritor de arquivo 2 se a chamada para abrir () falhar. Em um sistema Linux padrão, e provavelmente muitos Unices, '/ dev / tty' existe e é improvável que causar uma falha.

Em segundo lugar, o comentário no topo fornece uma quantidade limitada de explicação de por que eles caem de volta ao descritor de arquivo 2. Meu palpite é que stdin, stdout e stderr são bastante ligado a '/ dev / tty /' de qualquer maneira , a não ser redirecionado. E uma vez que a maioria dos redirecionamentos comuns para para stdin e / ou stdout (via tubulação ou < / >), mas com menos frequência para stderr, as probabilidades em são que usando stderr seria mais provável que seja de conexão para o "teclado".

A mesma pergunta com uma resposta em última análise, da pessoa que perguntou ele está em linuxquestions embora eles citar fonte ligeiramente diferente do less. E não, eu não entendo mais do mesmo, então eu não posso ajudar, além disso:)

Parece ser uma funcionalidade específica Linux que envia entrada do teclado para FD 2.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top