Como obter o tty em que o bash está sendo executado?

25

No segundo método proposto por esta página , obtém-se o tty no qual o bash está sendo executado com o comando:

ps ax | grep $$ | awk '{ print $2 }'

Eu pensei comigo que certamente isso é um pouco preguiçoso, listando todos os processos em execução apenas para extrair um deles. Não seria mais eficiente (também estou perguntando se isso apresentaria efeitos indesejados):

ps -p $$ | tail -n 1 | awk '{ print $2 }'

Para sua informação, deparei-me com esse problema porque, às vezes, o primeiro comando produzia duas (ou mais) linhas. Isso aconteceria aleatoriamente, quando houvesse outro processo em execução com um PID que contenha $$como substring. Na segunda abordagem, evito esses casos solicitando o PID que sei que quero.

Sheljohn
fonte
6
o mais eficiente de todos seria executar o ttycomando na sua sessão do bash. Se você insistir em usar ps-ps -p $$ -o tty=
iruvar

Respostas:

47

Simplesmente digitando tty:

$ tty 
/dev/pts/20

Simples demais e óbvio para ser verdade :)

Editar: O primeiro retorna também ptyo processo em execução, grepcomo você pode perceber:

$ ps ax | grep $$
28295 pts/20   Ss     0:00 /bin/bash
29786 pts/20   S+     0:00 grep --color=auto 28295

portanto, você precisaria filtrar o grep para obter apenas um resultado, o que está ficando feio:

ps ax | grep $$ | grep -v grep | awk '{ print $2 }'

ou usando

ps ax | grep "^$$" | awk '{ print $2 }'

(uma variante mais sã)

Jakuje
fonte
Sim, essa é a primeira solução sugerida (na verdade é tty | sed -e "s:/dev/::"). Mas acho que a segunda solução sugerida nessa página não é apenas ineficiente, mas também errada! Vou usar ttye parar de reclamar. :)
Sheljohn
O primeiro retorna também ptyo processo em execução, grepcomo você pode notar.
Jakuje 16/03
2
Você não precisa grepse estiver usando awk. por exemplo ps ax | awk "/^$$/ {print \$2}"- observe o uso de aspas duplas em vez de aspas simples e de escape \$2. Mas, como você diz, usar ttyé a solução correta.
cas
Grepping como esse pode resultar em correspondências falsas, por exemplo, se o seu PID for 10 e também houver um PID 103. Useawk -vpid=$$ '$1 == pid {print $2}'
Barmar
Estou apenas observando aqui que a geração ttyno node.js não funciona, enquanto os psamigos funcionam bem.
Steven Lu
17

Se você quiser ser mais eficiente, sim, você está certo que pspode filtrar apenas o processo em questão (e será mais correto, não correndo o risco de pegar comandos que por acaso têm o número do processo em seus nomes. ) Não apenas isso, mas pode ser dito para não gerar o cabeçalho (opção h), eliminando o tailprocesso, e exibir apenas o TTYcampo (opção o tty), eliminando o awkprocesso.

Então aqui está o seu comando reduzido:

ps hotty $$
Toby Speight
fonte
10

Outras maneiras de fazer isso:

readlink /dev/fd/0     #or 1 or 2 
readlink /proc/self/fd/0 #or 1 or 2
readlink -f /dev/stdin #or stdout or stderr; f to resolve recursively
#etc.

(Se você estiver em um shell cujo stdin, stdout e stderr não estão conectados ao seu terminal de controle, é possível obter um filedescriptor no terminal de controle abrindo /dev/tty:

( { readlink /dev/fd/0; } </dev/tty; ) </dev/null  >output 2>&1

)

Ou com ps:

ps h -o tty -p $$ #no header (h); print tty column; for pid $$
PSkocik
fonte
2
(1) Fico feliz que você tenha percebido que o atual / controlador tty de um processo não está associado a nenhum descritor de arquivo e não é garantido que ele esteja aberto em qualquer disco rígido. Mas, você tentou o comando que você oferece como solução alternativa para essa contingência? Quando eu tento, tudo o que recebo é /dev/tty, e não o controle tty (conforme relatado por ps). (2) Eu acredito que { readlink /dev/fd/0; } < /dev/ttyé (e sempre será) equivalente a readlink /dev/fd/0 < /dev/tty- você acredita de outra forma? Se sim, você pode justificar isso? (3) O segundo ponto e vírgula em seu comando (o seguinte /dev/tty) é desnecessário.
Scott
6

Apenas para completar, enquanto os outros comandos ps mencionados funcionam no Linux ps -p $$ -o tty=(como mencionado por @ 1_CR) é o mais portátil para todos os sistemas Unix modernos, pois usa apenas as opções definidas no Padrão Unix .

Random832
fonte
2

No shell interativo, pode-se usar o wcomando para isso. No exemplo abaixo, o wrelatório é executado por um usuário específico e, é claro, mostra TTY onde esse comando está sendo executado.

$ w
 11:20:08 up 5 min,  3 users,  load average: 0.34, 0.39, 0.20
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
xieerqi  :0       :0               11:15   ?xdm?   1:47   0.34s init --user
xieerqi  pts/0    :0               11:18   23.00s  0.05s  0.05s /bin/mksh
xieerqi  pts/10   :0               11:20    0.00s  0.03s  0.01s w
Sergiy Kolodyazhnyy
fonte