As instruções-chave no trecho abaixo (ou seja, além daquelas para imprimir etiquetas e linhas em branco, para espaçamento) vêm em pares. Em cada par, a primeira e a segunda declarações têm as formas tty...
e echo $(tty...)
, respectivamente.
echo stdin:
tty
echo $(tty)
echo
echo stdout:
tty <&1
echo $(tty <&1)
echo
echo stderr:
tty <&2
echo $(tty <&2)
Se eu originar um arquivo contendo este trecho (em uma sessão zsh
ou bash
, por exemplo), recebo a seguinte saída 1 (adicionei os números de linha posteriormente, para referência):
1 stdin:
2 /dev/pts/8
3 /dev/pts/8
4
5 stdout:
6 /dev/pts/8
7 not a tty
8
9 stderr:
10 /dev/pts/8
11 /dev/pts/8
Nesta saída, a linha gerada por echo $(tty <&1)
(linha 7) se destaca visivelmente, por dois motivos:
- é a única entre as
echo $(tty ...)
linhas -geradas (ou seja, as linhas 3, 7 e 11) que difere de suatty ...
contraparte -gerada, imediatamente anterior (linhas 2, 6 e 10); e - ele difere da saída (linha 11) do formalmente análogo
echo $(tty <&2)
.
P: Como essas duas discrepâncias são explicadas?
Para o registro, tentei encontrar a explicação para essas aparentes anomalias na página de manual para tty
, mas, até onde posso dizer, esta página não aborda essas questões 2 ; certamente não explicitamente 3 .
Esta pergunta foi motivada por alguns do código esta grande resposta a uma pergunta anterior minha.
1 Claro, o número real depois /dev/pts/
será diferente se eu mudar de terminal e provavelmente será diferente para você se você tentar a mesma coisa.
2 Na verdade, toda a seção DESCRIÇÃO da tty
página de manual disponível em meu sistema consiste em apenas uma frase: "Imprima o nome do arquivo do terminal conectado à entrada padrão.".
3 Aqui estou deixando em aberto a possibilidade de que alguém com mais conhecimento prévio do que eu possa deduzir da tty
página concisa do manual do comportamento ilustrado acima.
tty
relata (em seu stdout) o nome do dispositivo tty que é aberto em sua entrada padrão (seu fd 0).Dentro:
O que é curto para
O shell redireciona o fd 0 para o mesmo recurso que está aberto no fd 2 (faz a
dup2(2, 0)
em um novo processo e depois executatty
nesse processo. Assimtty
terá o mesmo recurso em seu fd 0 e 2 e escreverá em fd 1 o tty que está aberto em ambos (se houver).O mesmo acontece com:
Dentro:
no entanto, o fd 1 dessa substituição de comando vai para um pipe (e o shell lê o que
tty
sai na outra extremidade), não é o mesmo recurso para onde o fd 1echo
vai.Se você quiser saber o que tty está aberto em fd 1 e usar uma substituição de comando, você precisa de algo como:
Então, para o processo em execução
tty
, temos:Então
tty
pode escrever nesse pipe o caminho do dispositivo tty que está conectado ao stdout externo .Como o tty não precisa desse fd 3, você pode torná-lo um pouco mais limpo com:
Ou seja, feche-o depois de usá-lo para duplicá-lo para fd 0.