Menos recebe entrada de teclado de stderr?
-
10-07-2019 - |
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 ...
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.