Comment obtenir le tty dans lequel bash s'exécute?

25

Dans la deuxième méthode proposée par cette page , on obtient le tty dans lequel bash est exécuté avec la commande:

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

Je me suis dit que c'était sûrement un peu paresseux, listant tous les processus en cours uniquement pour en extraire un. Ne serait-il pas plus efficace (je demande également si cela introduirait des effets indésirables) de faire:

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

Pour info, je suis tombé sur ce problème car parfois la première commande produisait en fait deux (ou plus) lignes. Cela se produirait de manière aléatoire, lorsqu'un autre processus s'exécuterait avec un PID qui contient $$une sous-chaîne. Dans la deuxième approche, j'évite de tels cas en demandant le PID que je sais que je veux.

Sheljohn
la source
6
la plus efficace de toutes serait d'exécuter la ttycommande dans votre session bash. Si vous insistez pour utiliser ps-ps -p $$ -o tty=
iruvar

Réponses:

47

En tapant simplement tty :

$ tty 
/dev/pts/20

Trop simple et évident pour être vrai :)

Edit: Le premier vous renvoie également ptyle processus en cours, grepcomme vous pouvez le constater:

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

par conséquent, vous devrez filtrer le grep pour obtenir un seul résultat, qui devient moche:

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

ou en utilisant

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

(une variante plus saine d'esprit)

Jakuje
la source
Oui, c'est effectivement la première solution suggérée (en fait, elle l'est tty | sed -e "s:/dev/::"). Mais je pense que la deuxième solution suggérée sur cette page est non seulement inefficace, mais aussi fausse! Je vais utiliser ttyet arrêter de me plaindre cependant. :)
Sheljohn
Le premier vous renvoie également ptyle processus en cours, grepcomme vous pouvez le constater.
Jakuje
2
Vous n'avez pas besoin grepsi vous utilisez awk. par exemple ps ax | awk "/^$$/ {print \$2}"- notez l'utilisation des guillemets doubles plutôt que des guillemets simples et des caractères d'échappement \$2. Mais, comme vous le dites, l'utilisation ttyest la bonne solution.
cas
Grepping comme ça peut entraîner de fausses correspondances, par exemple si votre PID est 10 et qu'il y a aussi un PID 103. Utilisationawk -vpid=$$ '$1 == pid {print $2}'
Barmar
Je note juste ici que le frai ttydans node.js ne fonctionne pas du tout, tandis que pset les amis fonctionnent très bien.
Steven Lu
17

Si vous voulez être plus efficace, alors oui, vous avez raison, vous pspouvez filtrer uniquement le processus en question (et ce sera plus correct, sans courir le risque de prendre des commandes qui ont votre numéro de processus dans leurs noms). ). Non seulement cela, mais on peut lui dire de ne pas générer l'en-tête (option h), d'éliminer le tailprocessus et d'afficher uniquement leTTY champ (option o tty), éliminant le awkprocessus.

Voici donc votre commande réduite:

ps hotty $$
Toby Speight
la source
10

Autres façons de procéder:

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.

(Si vous êtes dans un shell dont stdin, stdout et stderr ne sont pas connectés à son terminal de contrôle, vous pouvez obtenir un descripteur de fichier sur le terminal de contrôle en ouvrant /dev/tty :

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

)

Ou avec ps:

ps h -o tty -p $$ #no header (h); print tty column; for pid $$
PSkocik
la source
2
(1) Je suis heureux que vous vous soyez rendu compte que le terminal actuel / de contrôle d'un processus n'est associé à aucun descripteur de fichier et qu'il n'est pas garanti qu'il soit ouvert sur un fd. Mais, avez-vous essayé la commande que vous proposez pour contourner cette éventualité? Quand je l'essaye, tout ce que je reçois est /dev/tty, et non le tty de contrôle (tel que rapporté par ps). (2) Je crois que { readlink /dev/fd/0; } < /dev/ttyc'est (et sera toujours) équivalent à readlink /dev/fd/0 < /dev/tty- croyez-vous le contraire? Si oui, pouvez-vous le justifier? (3) Le deuxième point-virgule de votre commande (celui qui suit /dev/tty) n'est pas nécessaire.
Scott
6

Juste pour être complet, alors que les autres commandes ps mentionnées fonctionnent sous Linux, ps -p $$ -o tty=(comme mentionné par @ 1_CR) est la plus portable pour tous les systèmes Unix modernes, car elle utilise uniquement les options définies dans la norme Unix .

Aléatoire832
la source
2

Dans le shell interactif, on pourrait utiliser la wcommande pour cela. Dans l'exemple ci-dessous, wsignale lui-même être exécuté par un utilisateur spécifique, et bien sûr, il montre TTY où cette commande est exécutée.

$ 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
la source