Jak zdobyć tty, w którym działa bash?

25

W drugiej metodzie zaproponowanej przez tę stronę otrzymujemy tty, w którym uruchamiany jest bash za pomocą polecenia:

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

Pomyślałem sobie, że z pewnością jest to trochę leniwe, wymieniając wszystkie uruchomione procesy tylko po to, aby wyodrębnić jeden z nich. Czy nie byłoby bardziej wydajne (pytam również, czy wprowadziłoby to niepożądane efekty):

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

Do twojej wiadomości natknąłem się na ten problem, ponieważ czasami pierwsze polecenie faktycznie dało dwie (lub więcej) linii. Stałoby się to losowo, gdy byłby uruchomiony inny proces z PID, który zawiera $$jako podłańcuch. W drugim podejściu unikam takich przypadków, żądając PID, o którym wiem, że chcę.

Sheljohn
źródło
6
najbardziej wydajne ze wszystkich byłoby uruchomienie ttypolecenia w sesji bash. Jeśli nalegasz na użycie ps-ps -p $$ -o tty=
iruvar

Odpowiedzi:

47

Po prostu wpisując tty:

$ tty 
/dev/pts/20

Zbyt proste i oczywiste, aby mogło być prawdziwe :)

Edycja: Pierwszy zwraca ci również ptyprzebieg procesu, grepjak możesz zauważyć:

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

dlatego musisz odfiltrować grep, aby uzyskać tylko jeden wynik, który staje się brzydki:

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

lub używając

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

(bardziej rozsądny wariant)

Jakuje
źródło
Tak, to rzeczywiście pierwsze sugerowane rozwiązanie (tak naprawdę jest tty | sed -e "s:/dev/::"). Myślę jednak, że drugie sugerowane rozwiązanie na tej stronie jest nie tylko nieefektywne, ale również błędne! Wykorzystam ttyi przestanę narzekać. :)
Sheljohn,
Pierwszy zwraca ci również ptyprzebieg procesu, grepjak możesz zauważyć.
Jakuje
2
Nie potrzebujesz, grepjeśli używasz awk. np. ps ax | awk "/^$$/ {print \$2}"- zwróć uwagę na użycie podwójnych cudzysłowów zamiast pojedynczych cudzysłowów i znak ucieczki \$2. Ale, jak mówisz, używanie ttyjest właściwym rozwiązaniem.
cas
Takie grepowanie może skutkować fałszywymi dopasowaniami, np. Jeśli twój PID wynosi 10, a także PID 103. Użyjawk -vpid=$$ '$1 == pid {print $2}'
Barmar
Po prostu ttyzauważam tutaj, że spawnowanie w node.js w ogóle nie działa, a psprzyjaciele działają dobrze.
Steven Lu
17

Jeśli chcesz być bardziej wydajny, to tak, masz rację, że psmożesz filtrować tylko do danego procesu (i będzie to bardziej poprawne, nie ryzykując wybrania poleceń, które akurat mają twój numer procesu w nazwie) ). Ponadto można powiedzieć, aby nie generował nagłówka (opcja h), eliminując tailproces i wyświetlał tylko TTYpole (opcja o tty), eliminując awkproces.

Oto twoje ograniczone polecenie:

ps hotty $$
Toby Speight
źródło
10

Inne sposoby na zrobienie tego:

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.

(Jeśli znajdujesz się w powłoce, której stdin, stdout i stderr nie są podłączone do terminala sterującego, możesz uzyskać deskryptor pliku do terminala sterującego, otwierając /dev/tty:

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

)

Lub z ps:

ps h -o tty -p $$ #no header (h); print tty column; for pid $$
PSkocik
źródło
2
(1) Cieszę się, że zdałeś sobie sprawę, że bieżący / kontrolujący tty procesu nie jest powiązany z żadnym deskryptorem pliku i nie ma gwarancji, że będzie otwarty na dowolnym fd. Ale czy wypróbowałeś polecenie, które oferujesz jako obejście tej sytuacji awaryjnej? Kiedy próbuję, dostaję wszystko /dev/tty, a nie kontrolny tty (jak donosi ps). (2) Wierzę, że { readlink /dev/fd/0; } < /dev/ttyjest (i zawsze będzie) równoważne readlink /dev/fd/0 < /dev/tty- czy wierzysz inaczej? Jeśli tak, czy możesz to uzasadnić? (3) Drugi średnik w twoim poleceniu (następny po /dev/tty) jest niepotrzebny.
Scott
6

Dla kompletności, podczas gdy inne wspomniane polecenia ps działają w systemie Linux ps -p $$ -o tty=(jak wspomniano w @ 1_CR) jest najbardziej przenośny dla wszystkich współczesnych systemów uniksowych, ponieważ używa tylko opcji zdefiniowanych w standardzie Unix .

Losowo 832
źródło
2

W interaktywnej powłoce można wdo tego użyć polecenia. W poniższym przykładzie wraporty są uruchamiane przez określonego użytkownika i, oczywiście, pokazuje TTY, gdzie to polecenie jest uruchamiane.

$ 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
źródło