Come ottenere il tty in cui è in esecuzione bash?


25

Nel secondo metodo proposto da questa pagina , si ottiene il tty in cui viene eseguito bash con il comando:

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

Ho pensato a me stesso che sicuramente questo è un po 'pigro, elencando tutti i processi in esecuzione solo per estrarne uno. Non sarebbe più efficiente (chiedo anche se questo introdurrebbe effetti indesiderati) per fare:

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

Cordiali saluti, mi sono imbattuto in questo problema perché a volte il primo comando avrebbe effettivamente prodotto due (o più) righe. Ciò accadrebbe in modo casuale, quando ci sarebbe un altro processo in esecuzione con un PID che contiene $$come sottostringa. Nel secondo approccio, sto evitando questi casi richiedendo il PID che so di volere.


6
ben più efficiente di tutti sarebbe eseguire il ttycomando all'interno della sessione bash. Se insisti nell'usare ps-ps -p $$ -o tty=
iruvar il

Risposte:


47

Digitando semplicemente tty:

$ tty 
/dev/pts/20

Troppo semplice e ovvio per essere vero :)

Modifica: il primo ti restituisce anche ptyil processo in esecuzione, grepcome puoi notare:

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

quindi dovresti filtrare il grep per ottenere un solo risultato, che sta diventando brutto:

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

o usando

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

(una variante più sana)


Sì, questa è davvero la prima soluzione suggerita (in realtà lo è tty | sed -e "s:/dev/::"). Ma penso che la seconda soluzione suggerita su quella pagina non sia solo inefficiente, ma anche sbagliata! Userò ttye smetterò di lamentarmi però. :)
Sheljohn,

Il primo ti restituisce anche ptyil processo in esecuzione, grepcome puoi notare.
Jakuje,

2
Non hai bisogno grepse stai usando awk. ad es. ps ax | awk "/^$$/ {print \$2}"- notare l'uso delle virgolette doppie anziché delle virgolette singole e degli escape \$2. Ma, come dici tu, usare ttyè la soluzione corretta.
Cas

Greppare in quel modo può provocare false corrispondenze, ad esempio se il tuo PID è 10 e c'è anche un PID 103. Usaawk -vpid=$$ '$1 == pid {print $2}'
Barmar

Sto solo notando che la ttygenerazione in node.js non funziona affatto, mentre gli psamici funzionano bene.
Steven Lu,

17

Se vuoi essere più efficiente, allora sì, hai ragione che pspuò filtrare solo il processo in questione (e sarà più corretto, non correndo il rischio di raccogliere comandi che hanno il tuo numero di processo nei loro nomi ). Non solo, ma si può dire di non generare l'intestazione (opzione h), eliminando il tailprocesso e di visualizzare solo il TTYcampo (opzione o tty), eliminando il awkprocesso.

Quindi ecco il tuo comando ridotto:

ps hotty $$

10

Altri modi per farlo:

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 ti trovi in ​​una shell il cui stdin, stdout e stderr non sono collegati al suo terminale di controllo, puoi ottenere un descrittore di file al terminale di controllo aprendo /dev/tty:

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

)

O con ps:

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

2
(1) Sono contento che tu abbia capito che l'attuale / controllo di un processo non è associato ad alcun descrittore di file e non è garantito che sia aperto su nessun fd. Ma hai provato il comando che offri come soluzione alternativa per quella contingenza? Quando lo provo, tutto ciò che ottengo è /dev/ttye non il controllo tty (come riportato da ps). (2) Credo che { readlink /dev/fd/0; } < /dev/ttysia (e sarà sempre) equivalente a readlink /dev/fd/0 < /dev/tty- credi diversamente? In tal caso, puoi giustificarlo? (3) Il secondo punto e virgola nel comando (quello successivo /dev/tty) non è necessario.
Scott,

6

Solo per completezza, mentre gli altri comandi ps menzionati funzionano su Linux, ps -p $$ -o tty=(come menzionato da @ 1_CR) è il più portatile per tutti i moderni sistemi Unix, poiché utilizza solo le opzioni definite nello Standard Unix .


2

Nella shell interattiva, si potrebbe usare il wcomando per quello. Nell'esempio seguente, wriporta se stesso eseguito da un utente specifico e ovviamente mostra TTY dove viene eseguito quel comando.

$ 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.