Як отримати tty, в якому працює баш?


25

У другому методі, запропонованому цією сторінкою , отримується tty, в якому баш виконується за допомогою команди:

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

Я хоч для себе, що напевно це трохи ліниво, перелічуючи всі запущені процеси лише для вилучення одного з них. Чи не було б більш ефективно (я також запитую, чи це спричинить небажані ефекти) робити:

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

FYI, я зіткнувся з цим питанням, оскільки іноді перша команда фактично давала два (або більше) рядків. Це станеться випадковим чином, коли буде інший процес, запущений з PID, який містить $$як підрядку. У другому підході я уникаю подібних випадків, запитуючи PID, який я знаю, що хочу.


6
а найефективнішим з усіх буде запускати ttyкоманду в рамках вашого сеансу bash. Якщо ви наполягаєте на використанні ps-ps -p $$ -o tty=
iruvar

Відповіді:


47

Просто ввівши tty:

$ tty 
/dev/pts/20

Занадто просто і очевидно, щоб бути правдою :)

Редагувати: Перший повертає вам також ptyтой процес, який виконується, grepяк ви можете помітити:

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

тому вам потрібно буде відфільтрувати grep, щоб отримати лише один результат, який стає некрасивим:

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

або використовуючи

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

(більш здоровий варіант)


Так, це справді перше запропоноване рішення (насправді воно є tty | sed -e "s:/dev/::"). Але я думаю, що друге запропоноване рішення на цій сторінці є не тільки неефективним, але й неправильним! Я все-таки використаю ttyі перестану скаржитися. :)
Шельон

Перший повертає вам також той ptyсамий процес, який виконується, grepяк ви можете помітити.
Jakuje

2
Вам не потрібно, grepякщо ви використовуєте awk. напр. ps ax | awk "/^$$/ {print \$2}"- відзначте використання подвійних лапок, а не одноцитат, а пропущених \$2. Але, як ви кажете, використання tty- це правильне рішення.
cas

Таке прискорення може призвести до помилкових збігів, наприклад, якщо ваш PID становить 10, а також PID 103. Використанняawk -vpid=$$ '$1 == pid {print $2}'
Barmar

Я просто зауважу тут, що нерест ttyу node.js взагалі не працює, а psдрузі працюють просто чудово.
Стівен Лу

17

Якщо ви хочете бути ефективнішими, то так, ви маєте рацію, що psможете фільтрувати лише до того процесу, про який йдеться (і це буде правильніше, не ризикуючи підбирати команди, які мають у своєму імені номер вашого процесу ). Мало того, але можна сказати не генерувати заголовок (параметр h), виключаючи tailпроцес, а відображати лише TTYполе (опцію o tty), виключаючи awkпроцес.

Отже ось ваша скорочена команда:

ps hotty $$

10

Інші способи зробити це:

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.

(Якщо ви знаходитесь в оболонці, чиї stdin, stdout та stderr не підключені до її керуючого терміналу, ви можете отримати fileescriptor до керуючого терміналу, відкривши /dev/tty:

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

)

Або з ps:

ps h -o tty -p $$ #no header (h); print tty column; for pid $$

2
(1) Я радий, що ти зрозумів, що поточний / керуючий tty процесу не пов'язаний з жодним дескриптором файлів і не гарантовано є відкритим на будь-якому fd. Але чи спробували ви команду, яку ви пропонуєте як спосіб вирішення цієї ситуації? Коли я спробую це, я отримую все /dev/tty, а не контрольний tty (як повідомляється ps). (2) Я вважаю, що { readlink /dev/fd/0; } < /dev/ttyце (і завжди буде) рівнозначне readlink /dev/fd/0 < /dev/tty- чи вірите ви в інше? Якщо так, чи можете ви це виправдати? (3) Друга крапка з комою у вашій команді (друга після /dev/tty) - зайва.
Скотт

6

Тільки для повноти, в той час як інші згадані команди PS працюють в Linux ps -p $$ -o tty=(як згадує @ 1_CR) є найбільш портативним для всіх сучасних систем Unix, оскільки він використовує лише параметри, визначені в Unix Standard .


2

В інтерактивній оболонці можна було використовувати wдля цього команду. У наведеному нижче прикладі, wзвіти виконуються конкретним користувачем, і, звичайно, він показує TTY, де ця команда виконується.

$ 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.